object - 返回 interface{} 而不是 int64 时的额外分配

标签 object memory go types allocation

我有一个生成随机 int64 并将其作为 interface{} 返回的函数,如下所示:

func Val1(rnd rand.Source) interface{} {
 return rnd.Int63() 
} 

现在考虑这个函数,它做同样的事情但是返回一个 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{} 时可以避免吗?

最佳答案

接口(interface)值是引擎盖下的包装器,是存储在接口(interface)值中的具体值及其类型描述符的一对。

阅读此内容了解更多信息:The Laws of Reflection #The representation of an interface

因此,如果您想返回一个 interface{} 类型的值,将隐式创建一个 interface{} 值(如果返回的值还不是该类型),它将保存整数及其表示 int64 类型的类型描述符。你无法避免这一点。

interface{} 是一种特殊的接口(interface)类型(具有 0 个方法)。正如您在基准测试输出中看到的,它的值只有 8 个字节。其他接口(interface)类型具有更大的大小(double),因为它们还必须标识接口(interface)类型的静态方法集(除了动态类型和值之外)。

另请务必查看此信息丰富的答案:Go: What's the meaning of interface{}?

如果您想了解有关实现/内部的更多信息,我推荐这篇文章:How Interfaces Work in Golang

关于object - 返回 interface{} 而不是 int64 时的额外分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45350097/

相关文章:

c - 当字符指针指向字符串时,如何分配内存?

http - Go http 客户端超时与上下文超时

c# - 调用方法与将对象分配给方法 AND void 返回类型与对象返回类型

php - 可捕获的 fatal error : Object of class dayDaytimeFields could not be converted to string

Java - 将值分配给实例变量时,应在此标记之后使用 VariableDeclaratorID

c++ - 1.exe : Microsoft C++ exception: std:out_of_range at memory location 0x0012fb8c中0x77e4bef7的未处理异常

java - 为什么这个java进程不释放内存?

go - 编写一个函数来从映射中获取一段字符串键,无论映射是什么值类型

docker - 运行docker image Standard_init_linux.go:211时出错:exec用户进程导致“没有这样的文件或目录”

javascript - 如何将 2 个 JSON 对象的特定值添加到新的 JSON 对象