如何使用基准的时间价值

huangapple go评论84阅读模式
英文:

How to use time value of benchmark

问题

我已经用Go语言为我的国际象棋引擎编写了一个基准测试:

func BenchmarkStartpos(b *testing.B) {
    board := ParseFen(startpos)
    for i := 0; i < b.N; i++ {
        Perft(&board, 5)
    }
}

当运行时,我看到了以下输出:

goos: darwin
goarch: amd64
BenchmarkStartpos-4   	      10	 108737398 ns/op
PASS
ok  	_/Users/dylhunn/Documents/go-chess	1.215s

我想使用每次执行的时间(在这个例子中为 108737398 ns/op)来计算另一个值,并将其作为基准测试的结果输出。具体来说,我想输出每秒节点数,即Perft调用的结果除以每次调用的时间。

我该如何获取基准测试的执行时间,以便我可以打印出自己计算得到的结果?

英文:

I have written a benchmark for my chess engine in Go:

func BenchmarkStartpos(b *testing.B) {
	board := ParseFen(startpos)
	for i := 0; i &lt; b.N; i++ {
		Perft(&amp;board, 5)
	}
}

I see this output when it runs:

goos: darwin
goarch: amd64
BenchmarkStartpos-4   	      10	 108737398 ns/op
PASS
ok  	_/Users/dylhunn/Documents/go-chess	1.215s

I want to use the time per execution (in this case, 108737398 ns/op) to compute another value, and also print it as a result of the benchmark. Specifically, I want to output nodes per second, which is given as the result of the Perft call divided by the time per call.

How can I access the time the benchmark took to execute, so I can print my own derived results?

答案1

得分: 10

你可以使用testing.Benchmark()函数来手动测量/基准测试“基准测试”函数(其签名为func(*testing.B)),并将结果作为testing.BenchmarkResult的值返回,该结构包含了你所需的所有细节:

type BenchmarkResult struct {
    N         int           // 迭代次数
    T         time.Duration // 总共花费的时间
    Bytes     int64         // 每次迭代处理的字节数
    MemAllocs uint64        // 总的内存分配次数
    MemBytes  uint64        // 总的字节分配数
}

每次执行的时间可以通过BenchmarkResult.NsPerOp()方法返回,你可以根据需要进行处理。

看下面这个简单的例子:

func main() {
    res := testing.Benchmark(BenchmarkSleep)
    fmt.Println(res)
    fmt.Println("Ns per op:", res.NsPerOp())
    fmt.Println("Time per op:", time.Duration(res.NsPerOp()))
}

func BenchmarkSleep(b *testing.B) {
    for i := 0; i < b.N; i++ {
        time.Sleep(time.Millisecond * 12)
    }
}

输出结果为(在Go Playground上尝试一下):

     100	  12000000 ns/op
Ns per op: 12000000
Time per op: 12ms
英文:

You may use the testing.Benchmark() function to manually measure / benchmark "benchmark" functions (that have the signature of func(*testing.B)), and you get the result as a value of testing.BenchmarkResult, which is a struct with all the details you need:

type BenchmarkResult struct {
	N         int           // The number of iterations.
	T         time.Duration // The total time taken.
	Bytes     int64         // Bytes processed in one iteration.
	MemAllocs uint64        // The total number of memory allocations.
	MemBytes  uint64        // The total number of bytes allocated.
}

The time per execution is returned by the BenchmarkResult.NsPerOp() method, you can do whatever you want to with that.

See this simple example:

func main() {
	res := testing.Benchmark(BenchmarkSleep)
	fmt.Println(res)
	fmt.Println(&quot;Ns per op:&quot;, res.NsPerOp())
	fmt.Println(&quot;Time per op:&quot;, time.Duration(res.NsPerOp()))
}

func BenchmarkSleep(b *testing.B) {
	for i := 0; i &lt; b.N; i++ {
		time.Sleep(time.Millisecond * 12)
	}
}

Output is (try it on the Go Playground):

     100	  12000000 ns/op
Ns per op: 12000000
Time per op: 12ms

huangapple
  • 本文由 发表于 2017年5月9日 15:31:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/43863794.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定