【问题标题】:Using testing.Benchmark does not produce any output使用 testing.Benchmark 不会产生任何输出
【发布时间】:2017-01-25 21:24:03
【问题描述】:

我正在使用testing.Benchmark 手动运行几个基准测试,但结果对象始终为空。

我错过了什么吗?

这是一个例子:

package main

import "testing"

func main() {

    result := testing.Benchmark(func(parentB *testing.B) {
        parentB.Run("example", func(b *testing.B) {
            for n := 0; n < b.N; n++ {
                println("ok")
            }
        })
    })

    println(result.String())

}

这将打印几次ok,然后打印0 0 ns/op,但基准测试显然确实运行了一些东西。

【问题讨论】:

  • 您是否尝试过一些“纯”计算,而不仅仅是打印?
  • 不确定我是否理解如何操作。
  • 好吧,没关系。我自己试过了,它确实不起作用,与文档相反。

标签: go


【解决方案1】:

我认为你做的一切都是正确的。 testing.Benchmark() 的文档说:

Benchmark 对单个函数进行基准测试。对于创建不使用“go test”命令的自定义基准测试很有用。

如果 f 调用 Run,则结果将是在单个基准测试中运行其所有未按顺序调用 Run 的子基准测试的估计值。

研究实施(Go 1.7.4):

func Benchmark(f func(b *B)) BenchmarkResult {
    b := &B{
        common: common{
            signal: make(chan bool),
            w:      discard{},
        },
        benchFunc: f,
        benchTime: *benchTime,
    }
    if !b.run1() {
        return BenchmarkResult{}
    }
    return b.run()
}

这一行:

    if !b.run1() {
        return BenchmarkResult{}
    }

b.run1() 应该运行您传递的函数一次,并检测它是否具有子基准。你的有。它返回 bool 是否需要更多运行。里面run1()

if b.hasSub || b.finished {
    // ...
    return true
}

它正确地告诉它有子基准,并且Benchmark()——非常简单——只返回一个空的BenchmarkResult

    if !b.run1() {
        return BenchmarkResult{}
    }

我确实认为这是一个错误(或者更确切地说是“不完整”的功能),或者文档不正确。我建议在这里提出问题:https://github.com/golang/go/issues

【讨论】:

    【解决方案2】:

    编辑了答案以澄清:

    我的猜测是您正在使用 go run 来运行测试。那不会产生任何结果。为了按照编写的方式运行代码,您需要使用
    去测试-bench=。我认为它应该工作。 该文件必须命名为 test_xxx.go,其中 xxx 是你想要的任何东西。

    如果你重构你的代码,它可以作为一个单一的函数基准运行:

    package main
    
    import "testing"
    
    func main() {
        myTest()
    }
    
    func myTest() {
        fn := func(b *testing.B) {
            for n := 0; n < b.N; n++ {
                println("ok")
            }
        }
        result := testing.Benchmark(fn)
    
        println(result.String())
    }
    

    【讨论】:

    • 'Benchmark 对单个函数进行基准测试。对于创建不使用“go test”命令的自定义基准测试很有用。'
    • 如果我不清楚,我很抱歉。要完全按照编写的代码运行代码,他需要使用 run -bench=。我将编辑我的原始答案,说明如何对其进行一些重组以使其测试单个功能。
    • @PeterFendrich 是的,不使用子基准是可行的。但是根据文档,提问者尝试的内容也应该有效(很可能他有更多的子基准,为了简洁起见,这些子基准没有包含在问题中),这就是这个问题的意义所在。
    • 是的,不使用 subs 工作,但这不是我要找的。​​span>
    猜你喜欢
    • 1970-01-01
    • 2022-01-10
    • 2017-02-03
    • 2012-01-18
    • 1970-01-01
    相关资源
    最近更新 更多