英文:
How to avoid heap allocation in anonymous function?
问题
以下是具有两个函数的示例代码。
匿名函数f0使用浮点数和字符串变量,但由于某种奇怪的原因,它将它们移动到堆上。有什么办法可以避免不必要的分配吗?
import (
"testing"
)
var _int int32 = 10
var _float float32 = 10
var _string = "go"
var f0 = func(v interface{}) {
_ = v
}
func f1(v interface{}) {
_ = v
}
func Benchmark(b *testing.B) {
for i := 0; i < b.N; i++ {
f0(_int)
f1(_int)
f0(_float) // <- 分配
f1(_float)
f0(_string) // <- 分配
f1(_string)
}
}
英文:
Here is the following example with two functions.
Anonymous function f0 however with float and string variables, for some strange reason, moves them to heap.
Any ideas how to avoid unnecessary allocations?
import (
"testing"
)
var _int int32 = 10
var _float float32 = 10
var _string = "go"
var f0 = func(v interface{}) {
_ = v
}
func f1(v interface{}) {
_ = v
}
func Benchmark(b *testing.B) {
for i := 0; i < b.N; i++ {
f0(_int)
f1(_int)
f0(_float) // <- alloc
f1(_float)
f0(_string) // <- alloc
f1(_string)
}
}
答案1
得分: 2
由于您的函数的参数类型是interface{}
,当值传递给它们时,必须创建一个隐式接口值。这个接口值的创建需要分配内存。
这不会发生在f1()
中,因为该函数将被内联。
这也不会发生在_int
上,因为它是一个"小"整数值,并且Go 1.5添加了优化,将小整数(0到255)包装在接口值中,因此不需要分配内存。
请注意,如果将_int
的值更改为大于255
,那也将需要分配内存:
var _int int32 = 1000 // 当传递给f0()时,这也将需要分配内存
英文:
Since the parameter type of your functions is interface{}
, an implicit interface value have to be created when values are passed to them. This interface value creation is what requires allocation.
It does not happen with f1()
because that function will be inlined.
It also doesn't happen with _int
because it's a "small" integer value and Go 1.5 added optimization to wrap small integers (0 to 255) in interface values, hence not requiring allocation.
Note that if you change value of _int
to bigger than 255
, that will also require an allocation:
var _int int32 = 1000 // This will also require allocation when passed to f0()
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论