有什么更有效的方法,可以返回指向uint或uint的指针?

时间:2019-02-21 12:00:16

标签: performance pointers go

在Go中,从函数返回更有效的方法是:返回uint或返回*uint

该函数在CPU密集型库的内部for循环中调用。

1 个答案:

答案 0 :(得分:12)

通常,只要效率是问题,就应该运行基准测试。

让我们创建非常简单的示例:

func fuint() uint {
    return 0
}

func fpuint() *uint {
    var i uint
    return &i
}

以及基准代码:

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()
    }
}

要注意的一件事:由于我们的函数非常简单,因此代码优化可能会使结果无用(例如,我们可能会看到相同的结果)。

因此,相反,我们应该通过禁用编译器优化进行测试。因此,让我们像这样测试它:

go test -gcflags '-N -l' -bench . -benchmem

测试结果:

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

就像我们已经猜到的那样:分配uint值并返回指向它的指针比较慢,并且需要分配(在堆上),而返回简单的uint则不需要。 / p>

但不要总是这样。在此测试期间,我们禁用了编译器优化。当您将应用程序编译到生产环境时,显然不会禁用优化,因此您的实际示例可能没有太大差异,或者根本没有差异。测试/基准测试您的实际代码,看看返回指针是否真的有任何明显的区别。

作为参考,以下是启用编译器优化(默认行为)的结果:

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

在上面的特定示例中,我们发现fuint()fpuint()完全没有区别。