首页 > 解决方案 > 如何对 init() 函数进行基准测试

问题描述

我正在使用以下 Go 代码,该代码使用查找表计算人口计数:

package population

import (
        "fmt"
)

var pc [256]byte

func init(){
        for i := range pc {
                pc[i] = pc[i/2] + byte(i&1)
        }
}

func countPopulation() {
        var x uint64 = 65535
        populationCount := int(pc[byte(x>>(0*8))] +
                pc[byte(x>>(1*8))] +
                pc[byte(x>>(2*8))] +
                pc[byte(x>>(3*8))] +
                pc[byte(x>>(4*8))] +
                pc[byte(x>>(5*8))] +
                pc[byte(x>>(6*8))] +
                pc[byte(x>>(7*8))])

        fmt.Printf("Population count: %d\n", populationCount)
}

我编写了以下基准代码来检查上述代码块的性能:

package population

import "testing"

func BenchmarkCountPopulation(b *testing.B) {
        for i := 0; i < b.N; i++ {
                countPopulation()
        }
}

这给了我以下结果:

100000             18760 ns/op
PASS
ok      gopl.io/ch2     2.055s

然后我将代码从init()函数移动到countPopulation()函数,如下所示:

func countPopulation() {
        var pc [256]byte

        for i := range pc {
                pc[i] = pc[i/2] + byte(i&1)
        }

        var x uint64 = 65535
        populationCount := int(pc[byte(x>>(0*8))] +
                pc[byte(x>>(1*8))] +
                pc[byte(x>>(2*8))] +
                pc[byte(x>>(3*8))] +
                pc[byte(x>>(4*8))] +
                pc[byte(x>>(5*8))] +
                pc[byte(x>>(6*8))] +
                pc[byte(x>>(7*8))])

        fmt.Printf("Population count: %d\n", populationCount)
}

并再次运行相同的基准代码,这给了我以下结果:

100000             20565 ns/op
PASS
ok      gopl.io/ch2     2.303s

观察两个结果后,很明显该init()函数不在基准函数的范围内。这就是为什么与第二次执行相比,第一次执行基准测试花费的时间更少。

现在我有另一个问题,我正在寻找答案。

如果我只需要对init()方法进行基准测试,考虑到一个包中可以有多个init()函数。它是如何完成的golang

提前致谢。

标签: go

解决方案


init()的,一个包中可以有多个 ',事实上init(),一个文件中可以有多个 '。更多关于 init 的信息可以在这里找到。请记住,它init()会在您的程序启动之前自动调用一次main()

基准框架多次运行您的代码(在您的情况下为 100000)。这允许它测量非常短的函数以及非常长的函数。基准包括时间是没有意义的init()。您遇到的问题是您不了解基准测试的目的。基准测试可让您比较两个或多个单独的实现以确定哪个更快(您也可以根据相同函数的输入比较性能)。它没有告诉你应该在哪里做。

您基本上在做的事情被称为过早优化。这是您开始优化代码的地方,试图使其尽可能快,而不知道您的程序实际上将大部分时间花在了哪里。分析是测量程序的时间和空间复杂度的过程。在实践中,它可以让你看到你的程序大部分时间都花在了哪里。使用这些信息,您可以编写更高效的函数。有关 go 中的分析的更多信息,请参阅此博客文章


推荐阅读