Hi all.
It would be great eliminating heap allocations when passing the following standard Go types to functions accepting empty interfaces:
- 64-bit int (int64, uint64, int on x64)
- float64
- string
- slice
These heap allocations may slow down code with the following quite common functions accepting empty interface arguments:
- fmt.Printf-like functions
- Query and Exec functions from database/sql
- sync.Pool.Put
I understand that such types as string and slice cannot fit into word-sized 'data' field from interface struct. But the interface struct could be extended by two additional words when string or slice is passed to an interface{} function argument. As for []interface{} type, which is frequently used for passing arguments in Printf-like variadic functions, it could always point to an array of 4-word-sized interface structs. I believe extending interface{} size from 2 words to 4 words for passing function arguments will result in higher performance comparing to a heap allocation per each such argument as it works today.
Below is a memory profile dump generated with 'go tool pprof --alloc_objects' from
this benchmark code .
. . 23: for i := 0; i < b.N; i++ {
. 18274275 24: n += f(m)
. 4128831 25: n += f(ch)
. 1998878 26: n += f(n32)
1966110 4259905 27: n += f(n64)
1638425 3735609 28: n += f(nn)
. 1703962 29: n += f(f32)
2490406 4751432 30: n += f(f64)
4620358 7307375 31: n += f(str)
4030587 7880944 32: n += f(slice)
. . 33:
. 17695343 34: n += f(&m)
. 3735609 35: n += f(&ch)
. 3604535 36: n += f(&n32)
. 4259905 37: n += f(&n64)
. 4751432 38: n += f(&nn)
. 4063294 39: n += f(&f32)
. 4128831 40: n += f(&f64)
. 4128831 41: n += f(&str)
. 10535197 42: n += f(&slice)
. . 43: }