如何避免在匿名函数中进行堆分配?

huangapple go评论94阅读模式
英文:

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 (
	&quot;testing&quot;
)

var _int int32 = 10
var _float float32 = 10
var _string = &quot;go&quot;

var f0 = func(v interface{}) {
	_ = v
}

func f1(v interface{}) {
	_ = v
}

func Benchmark(b *testing.B) {
	for i := 0; i &lt; b.N; i++ {
		f0(_int)
		f1(_int)
		f0(_float) // &lt;- alloc
		f1(_float)
		f0(_string) // &lt;- 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()

huangapple
  • 本文由 发表于 2021年8月3日 04:01:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/68627339.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定