Package hrtime implements high-resolution timing functions and benchmarking utilities.
hrtime relies on using the best timing mechanism on a particular system. At the moment, for Windows it is using Performance Counters and on other platforms standard time.Now (since it's good enough).
Package also supports using hardware time stamp counters (TSC). They offer better accuracy and on some platforms correspond to the processor cycles. However, they are not supported on all platforms.
For example measuring time.Sleep on Mac and Windows.
package main
import (
"fmt"
"time"
"github.com/loov/hrtime"
)
func main() {
start := hrtime.Now()
time.Sleep(1000 * time.Nanosecond)
fmt.Println(hrtime.Since(start))
const numberOfExperiments = 4096
bench := hrtime.NewBenchmark(numberOfExperiments)
for bench.Next() {
time.Sleep(1000 * time.Nanosecond)
}
fmt.Println(bench.Histogram(10))
}Output on Mac:
12Β΅s
avg 14.5Β΅s; min 2Β΅s; p50 12Β΅s; max 74Β΅s;
p90 22Β΅s; p99 44Β΅s; p999 69Β΅s; p9999 74Β΅s;
2Β΅s [ 229] βββ
10Β΅s [3239] ββββββββββββββββββββββββββββββββββββββββ
20Β΅s [ 483] ββββββ
30Β΅s [ 80] β
40Β΅s [ 39] β
50Β΅s [ 17] β
60Β΅s [ 6]
70Β΅s [ 3]
80Β΅s [ 0]
90Β΅s [ 0]
Output on Windows:
1.5155ms
avg 1.49ms; min 576Β΅s; p50 1.17ms; max 2.47ms;
p90 2.02ms; p99 2.3ms; p999 2.37ms; p9999 2.47ms;
577Β΅s [ 1]
600Β΅s [ 57] ββ
800Β΅s [ 599] βββββββββββββββββ
1ms [1399] ββββββββββββββββββββββββββββββββββββββββ
1.2ms [ 35] β
1.4ms [ 7]
1.6ms [ 91] βββ
1.8ms [ 995] ββββββββββββββββββββββββββββ
2ms [ 778] ββββββββββββββββββββββ
2.2ms [ 134] ββββ
A full explanation why it outputs this is out of the scope of this document. However, all sleep instructions have a specified granularity and time.Sleep actual sleeping time is requested time Β± sleep granularity. There are also other explanations to that behavior.
hrtime/hrtesting can be used to supplement existing benchmarks with more details:
package hrtesting_test
import (
"fmt"
"runtime"
"testing"
"github.com/loov/hrtime/hrtesting"
)
func BenchmarkReport(b *testing.B) {
bench := hrtesting.NewBenchmark(b)
defer bench.Report()
for bench.Next() {
r := fmt.Sprintf("hello, world %d", 123)
runtime.KeepAlive(r)
}
}