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.

Reply via email to