On Tue, Aug 1, 2017 at 2:43 PM, roger peppe <rogpe...@gmail.com> wrote:

> 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)
>

Ah, I see. Thanks for the clarification. That makes sense to allocate just
one for the whole operation.


>
> > 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.
>
>
Ugh. I did not realize that. I had not dug into it too much other than
reading a Go blog post and this article by Russ Cox
<https://research.swtch.com/interfaces> (which suggest this memory
optimization is done).

I am guessing the conditional that decides between inline value vs.
pointer-chasing was too much runtime overhead?


> 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