Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Go implicit conversion to interface does memory allocation?

Tags:

go

When defining a function with variadic arguments of type interface{} (e.g. Printf), the arguments are apparently implicitly converted to interface instances.

Does this conversion imply memory allocation? Is this conversion fast? When concerned by code efficiency, should I avoid using variadic functions?

like image 877
chmike Avatar asked Sep 14 '16 14:09

chmike


People also ask

How does Golang allocate memory?

Go uses OS function mmap similar to TCMalloc (Thread-Caching Malloc) to allocate memory in heap. Go uses goroutine, which maintain a small stack (memory segment) act as memory pool for some memory blocks. The maximum stack size is 1 GB on 64-bit systems, and 250 MB on 32-bit systems, can be set by SetMaxStack function.

Does Go allocate& on stack or heap?

Go prefers allocation on the stack — most of the allocations within a given Go program will be on the stack. It's cheap because it only requires two CPU instructions: one to push onto the stack for allocation, and another to release from the stack. Unfortunately not all data can use memory allocated on the stack.

Does Go have heap?

All goroutines share a common heap and anything that can't be stored on the stack will end up there.

How does interfaces work in Go?

Go language interfaces are different from other languages. In Go language, the interface is a custom type that is used to specify a set of one or more method signatures and the interface is abstract, so you are not allowed to create an instance of the interface.


1 Answers

The best explanation i found about the interface memory allocation in Go is still this article from Rus Cox, one of the core Go programmer. It's well worth to read it.

http://research.swtch.com/interfaces

I picked up some of the most interesting parts:

Values stored in interfaces might be arbitrarily large, but only one word is dedicated to holding the value in the interface structure, so the assignment allocates a chunk of memory on the heap and records the pointer in the one-word slot.

...

Calling fmt.Printf(), the Go compiler generates code that calls the appropriate function pointer from the itable, passing the interface value's data word as the function's first (in this example, only) argument.

Go's dynamic type conversions mean that it isn't reasonable for the compiler or linker to precompute all possible itables: there are too many (interface type, concrete type) pairs, and most won't be needed. Instead, the compiler generates a type description structure for each concrete type like Binary or int or func(map[int]string). Among other metadata, the type description structure contains a list of the methods implemented by that type.

...

The interface runtime computes the itable by looking for each method listed in the interface type's method table in the concrete type's method table. The runtime caches the itable after generating it, so that this correspondence need only be computed once.

...

If the interface type involved is empty—it has no methods—then the itable serves no purpose except to hold the pointer to the original type. In this case, the itable can be dropped and the value can point at the type directly.

Because Go has the hint of static typing to go along with the dynamic method lookups, it can move the lookups back from the call sites to the point when the value is stored in the interface.

like image 50
Endre Simo Avatar answered Sep 21 '22 22:09

Endre Simo