nil*_*nus 1 performance pointers go
在Go中,从函数返回的效率更高:返回uint或返回*uint?
该函数在cpu密集型库的内部for循环中调用.
icz*_*cza 12
一般来说,只要效率是问题,就应该运行基准测试.
让我们创建非常简单的例子:
func fuint() uint {
return 0
}
func fpuint() *uint {
var i uint
return &i
}
Run Code Online (Sandbox Code Playgroud)
基准代码:
func BenchmarkUint(b *testing.B) {
for i := 0; i < b.N; i++ {
fuint()
}
}
func BenchmarkPuint(b *testing.B) {
for i := 0; i < b.N; i++ {
fpuint()
}
}
Run Code Online (Sandbox Code Playgroud)
需要注意的一件事是:由于我们的函数非常简单,因此代码优化可能会导致结果失效(例如,我们可能会看到相同的结果).
所以我们应该通过禁用编译器优化来测试.所以让我们这样测试一下:
go test -gcflags '-N -l' -bench . -benchmem
Run Code Online (Sandbox Code Playgroud)
测试结果:
BenchmarkUint-4 500000000 3.21 ns/op 0 B/op 0 allocs/op
BenchmarkPuint-4 100000000 22.4 ns/op 8 B/op 1 allocs/op
Run Code Online (Sandbox Code Playgroud)
正如我们可能已经猜到的那样:分配一个uint值并返回指向它的指针更慢并且需要分配(在堆上),而返回一个简单的uint值则不然.
但不要以为情况总是如此.在此测试期间,我们禁用了编译器优化.当您将应用程序编译为生产时,显然不会禁用优化,因此您的实际示例可能没有那么大的差异,或者根本没有差异.测试/测试您的实际代码,看看返回指针实际上是否会产生明显的差异.
作为参考,这是启用编译器优化的结果(默认行为):
go test -bench . -benchmem
BenchmarkUint-4 2000000000 0.35 ns/op 0 B/op 0 allocs/op
BenchmarkPuint-4 2000000000 0.35 ns/op 0 B/op 0 allocs/op
Run Code Online (Sandbox Code Playgroud)
我们看到没有任何区别fuint(),并fpuint()在所有在上面的具体例子.