On 1 August 2017 at 19:33, Josh Humphries <jh...@bluegosling.com> wrote: > On Tue, Aug 1, 2017 at 11:44 AM, roger peppe <rogpe...@gmail.com> wrote: >> >> On 1 August 2017 at 13:57, Josh Humphries <jh...@bluegosling.com> wrote: >> > Although that solution creates a heap-allocated tmp for every element in >> > the >> > slice. Using an interface, the value will be inlined instead of >> > heap-allocated if it fits without boxing (so most primitive types and >> > pointer types won't need heap allocation). >> >> As it happens, it's the other way round - the solution using Interface can >> make an allocation per element, but the solution using Value does not. > > > The solution using Value is calling reflect.New inside the loop. Why do you > say that it does not make an allocation per element?
The code I posted doesn't call reflect.New inside the loop - perhaps you're looking at some different code? (for the record, I'm talking about line 45 of https://play.golang.org/p/Q0VHbfL7Ij) > Also, I'm not sure I follow that using Interface makes an allocation per > element. My understanding is that the actual value can be stored in the > interface value if it is small enough (1 or 2 words?). So boxing primitives > and pointers should generally store the value in the interface tuple (which > itself is stack allocated) as opposed to allocating heap space for it and > storing a pointer. As I think was pointed out earlier in this thread, this has changed since Go 1. Only pointer values are stored in interface values now - non-pointer value (for example the ints in the example) will usually cause an allocation. There are some optimisations for some cases that avoid that: creation of an interface from a constant value, and creation of an interface from small numeric values. Try running the benchmark code that I posted. I think you'll find that the code that calls Interface is slower and allocates more, because it has to allocate a storage slot every time it creates an interface from an int, which the solution using Value does not, because it allocates the temporary only once for a given call to Reverse (even that could be amortised by using sync.Pool, but it's almost certainly not worth it). cheers, rog. -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.