On Tue, Dec 6, 2016 at 8:08 AM, Francis <francissteph...@gmail.com> wrote:
> Today I was exploring some unexpected allocations that came from creating
> empty interface{} values wrapping a string and an int. I spent some time
> trying to clarify my understanding so I wouldn't be surprised in the future.
>
> I have consulted this excellent page http://research.swtch.com/interfaces
> and written a small set of benchmarks. I am running Go 1.7
>
> My understanding of an interface is that it is made up of a pair of
> pointers. The first is a pointer to an itable containing the concrete type
> and a table of functions. The second pointer is to the data itself. We can
> write this [*itable, *data].
>
> If we want to create an interface{} wrapping a string then we need to be
> able to point to its itable and to the string itself. We assume the itable
> already exists and we can point to it efficiently. However, although a
> string behaves like a pointer it is a complex value containing [*data,
> length] (I'll call this data structure a string-descriptor), so we can't
> just use that as a pointer in our interface. We need to allocate the
> string-descriptor, and the interface can then point to that location on the
> heap.
>
> This is broadly true of most values in Go, as many pointer-like things are
> actually complex values. But we would expect that an interface wrapping an
> actual pointer wouldn't need to allocate at all.
>
> The benchmarks in the gist below seem to confirm that. However, there were a
> mistakes and false paths in putting these benchmarks together so I would
> appreciate it if someone could confirm that what I have described above is
> true. And if it is not true, could you please clarify.

What you describe above is true.  I'll note that not all Go
implementations implement interfaces in exactly the same way.

Additional complexities are that the gc implementation treats
functions, maps, and channels as pointer values, and does the same for
single-element arrays and single-field structs with the single element
or field is itself a pointer value (recursively defined).  Also, note
that zero-length values are always allocated to the same address, and
as such do not take up any space in the heap.

Ian

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