【问题标题】:Golang Benchmark table test, can I extract func from b.Run()?Golang Benchmark 表测试,我可以从 b.Run() 中提取 func 吗?
【发布时间】:2017-11-24 15:05:58
【问题描述】:

按照 golang 中的基准示例测试,我可以进行以下测试:

// An example benchmark to benchmark a query based on different inputs
func Benchmark_GetProcessingCountForRegions(b *testing.B) {

    benchmarks := []struct {
        region string
    }{
        {"EU"},
        {"US"},
    }

    for _, bm := range benchmarks {
        b.Run(bm.region, func(bbb *testing.B) {
            for i := 0; i < bbb.N; i++ {
                taskDb.GetProcessingCountForRegion(bm.region)
            }
        })

    }
}

这是来自网络的默认示例,适用于我;测试 taskDb 包的 GetProcessingCountForRegion 查询性能。

但是为了这个测试的可读性,我试图提取内部 func,即位于 b.Run() 中的那个,就像这样,首先提取 func 并将其放在一边:

func GetProcessingCountForRegion(testingB *testing.B, region string) {
    for i := 0; i < testingB.N; i++ {
        taskDb.GetProcessingCountForRegion(region)
    }
}

然后像这样在实际的 testfunc 中使用这个函数:

for _, bm := range benchmarks {
        b.Run(bm.region, GetProcessingCountForRegion(*b, bm.region))
}

但是这会产生编译错误: 不能在 GetProcessingCountForRegion 的参数中使用 *b (type testing.B) 作为 *testing.B 类型

从 *b 中删除 *,会产生以下编译错误: GetProcessingCountForRegion(b, bm.region) 用作值

所以我想要的是从 B.Run(..) 语句中删除 func 参数。

我错过了什么?

【问题讨论】:

    标签: testing go


    【解决方案1】:

    例如,

    bench_test.go:

    package main
    
    import "testing"
    
    func GetProcessingCountForRegion(region string) int {
        return 42
    }
    
    func benchmarkGetProcessingCountForRegion(b *testing.B, region string) {
        for i := 0; i < b.N; i++ {
            GetProcessingCountForRegion(region)
        }
    }
    
    func BenchmarkGetProcessingCountForRegions(b *testing.B) {
        benchmarks := []struct {
            region string
        }{
            {"EU"},
            {"US"},
        }
    
        for _, bm := range benchmarks {
            b.Run(bm.region,
                func(b *testing.B) {
                    benchmarkGetProcessingCountForRegion(b, bm.region)
                },
            )
        }
    }
    

    输出:

    $ go test -bench=.
    BenchmarkGetProcessingCountForRegions/EU-4    2000000000    1.17 ns/op
    BenchmarkGetProcessingCountForRegions/US-4    2000000000    1.17 ns/op
    

    【讨论】:

    • 我相信这更接近我想要的,但我想从 b.Run(..) 语句中删除 func() 参数。我认为在您的帮助下找到了 Closure 的解决方案,我将把它作为答案发布,让我知道您的想法。
    【解决方案2】:

    我想我找到了使用“闭包”的答案,即定义一个返回 func(*testing.B) 的函数,可以在 b.Run(..., namedMethod)..

    代码:

    func Benchmark_GetProcessingCountForRegions(b *testing.B) {
        benchmarks := []struct {
            region string
        }{
            {"EU"},
            {"US"},
        }
        for _, bm := range benchmarks {
            f := GetProcessingCountForRegion(bm.region)
            b.Run(bm.region, f)
        }
    }
    
    // GetProcessingCountForRegion is the closure function
    func GetProcessingCountForRegion(region string) func(*testing.B) {
        return func(b *testing.B) {
            for i := 0; i < b.N; i++ {
                taskDb.GetProcessingCountForRegion(region)
    
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-08-22
      • 1970-01-01
      • 2010-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多