func BenchmarkCheap(b *testing.B) {
b.StopTimer()
s := Expensive()
b.StartTimer()
for i := 0; i < b.N; i++ {
s.Cheap()
}
}
A loop body like the one you have will never have
an accurate result, no matter how many times the
benchmark runs the loop - because Expensive is
dominating everything - so there's little point in
adjusting the way the benchmark chooses N.
Russ
Including the "timer off" operations in the
computation of b.N will mean that the benchmarks
take too small a b.N.
I think your use case is just not supported by
the benchmark framework. In fact it's hard to
see how it would be supported by any benchmark
framework unless you used cycle counters or
something like that.
Russ
The point of b.N is to make the timed test take long enough
to get a meaningful measurement; then you divide by b.N
to get the per-operation time. Right now that means you
increase b.N until the loop takes >1 second.
In this case:
func BenchmarkCheap(b *testing.B) {
b.StopTimer()
s := Expensive()
b.StartTimer()
for i := 0; i < b.N; i++ {
s.Cheap()
}
}
if Expensive takes more than a second, then you
must exclude that time from the decision about
whether N is large enough. If you include it - as your
original mail suggested - then it will choose N==1,
which is not good enough to get an accurate measurement
when the timer is off for most of the test.
Also StartTimer and StopTimer have a cost too.
If you call them N times, then you have to worry
about compensating for that.
Russ
One could try that, but the whole point of doing things
N times for some large N is that the tiny operations
tend to be smaller than the resolution of the timer,
StopTimer and StartTimer included. It is far better
not to call them in the loop.
In the case you gave I would instead make N the
number of items to Pop.
Russ
No.
package main
import (
"container/heap"
"container/vector"
"fmt"
"rand"
"testing"
)
type v struct {
vector.IntVector
}
func (v *v) Push(x interface{}) {
v.IntVector.Push(x.(int))
}
func (v *v) Pop() interface{} {
return v.IntVector.Pop()
}
var h v
func BenchmarkHeap(b *testing.B) {
b.StopTimer()
for i := 0; i < b.N; i++ {
heap.Push(&h, rand.Int())
}
b.StartTimer()
for i := 0; i < b.N; i++ {
heap.Pop(&h)
}
}
func main() {
fmt.Println(testing.Benchmark(BenchmarkHeap))
}