返回 interface{} 而不是 int64 时的额外分配
extra allocation when returning interface{} instead of int64
我有一个生成随机 int64
和 returns 的函数,它作为 interface{}
像这样:
func Val1(rnd rand.Source) interface{} {
return rnd.Int63()
}
现在考虑这个函数,它做同样的事情但是 returns int64
func Val2(rnd rand.Source) int64 {
return rnd.Int63()
}
我用这个 (go test -bench=. -benchmem
) 对这两个函数进行了基准测试:
func BenchmarkVal1(b *testing.B) {
var rnd = rand.NewSource(time.Now().UnixNano())
for n := 0; n < b.N; n++ {
Val1(rnd)
}
}
func BenchmarkVal2(b *testing.B) {
var rnd = rand.NewSource(time.Now().UnixNano())
for n := 0; n < b.N; n++ {
Val2(rnd)
}
}
得到以下结果:
BenchmarkVal1-4 50000000 32.4 ns/op 8 B/op 1 allocs/op
BenchmarkVal2-4 200000000 7.47 ns/op 0 B/op 0 allocs/op
Val1()
中的额外分配从何而来?返回 interface{}
时可以避免吗?
接口值是引擎盖下的包装器,是存储在接口值中的具体值及其类型描述符的一对。
阅读此内容了解更多信息:The Laws of Reflection #The representation of an interface
因此,如果您想 return 一个 interface{}
类型的值,将隐式创建一个 interface{}
值(如果 returned 的值尚未该类型),它将保存整数及其表示 int64
类型的类型描述符。你无法避免这一点。
interface{}
是一种特殊的接口类型(有 0 个方法)。正如您在基准测试输出中看到的,它的值只有 8 个字节。其他接口类型具有更大的大小(双精度),因为它们还必须标识接口类型的静态方法集(除了动态类型和值)。
另外请务必查看这个信息丰富的答案:Go: What's the meaning of interface{}?
如果您想了解有关实现/内部的更多信息,我推荐这个 post:How Interfaces Work in Golang
我有一个生成随机 int64
和 returns 的函数,它作为 interface{}
像这样:
func Val1(rnd rand.Source) interface{} {
return rnd.Int63()
}
现在考虑这个函数,它做同样的事情但是 returns int64
func Val2(rnd rand.Source) int64 {
return rnd.Int63()
}
我用这个 (go test -bench=. -benchmem
) 对这两个函数进行了基准测试:
func BenchmarkVal1(b *testing.B) {
var rnd = rand.NewSource(time.Now().UnixNano())
for n := 0; n < b.N; n++ {
Val1(rnd)
}
}
func BenchmarkVal2(b *testing.B) {
var rnd = rand.NewSource(time.Now().UnixNano())
for n := 0; n < b.N; n++ {
Val2(rnd)
}
}
得到以下结果:
BenchmarkVal1-4 50000000 32.4 ns/op 8 B/op 1 allocs/op
BenchmarkVal2-4 200000000 7.47 ns/op 0 B/op 0 allocs/op
Val1()
中的额外分配从何而来?返回 interface{}
时可以避免吗?
接口值是引擎盖下的包装器,是存储在接口值中的具体值及其类型描述符的一对。
阅读此内容了解更多信息:The Laws of Reflection #The representation of an interface
因此,如果您想 return 一个 interface{}
类型的值,将隐式创建一个 interface{}
值(如果 returned 的值尚未该类型),它将保存整数及其表示 int64
类型的类型描述符。你无法避免这一点。
interface{}
是一种特殊的接口类型(有 0 个方法)。正如您在基准测试输出中看到的,它的值只有 8 个字节。其他接口类型具有更大的大小(双精度),因为它们还必须标识接口类型的静态方法集(除了动态类型和值)。
另外请务必查看这个信息丰富的答案:Go: What's the meaning of interface{}?
如果您想了解有关实现/内部的更多信息,我推荐这个 post:How Interfaces Work in Golang