Skip to content
High resolution timing and benchmarking for Go
Go Assembly
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
_example use p999 as clamping value Feb 20, 2019
hrplot bump version Apr 4, 2019
hrtesting rename Measurements -> Float64s Apr 2, 2019
.gitignore benchtime: fix ps May 1, 2018
LICENSE Add license Apr 11, 2018
README.md remove beta marking Apr 3, 2019
benchmark.go add Name method to satisfy hrplot.Benchmark interface Apr 2, 2019
benchmark_test.go make examples clearer about iteration count Feb 18, 2019
benchmarktsc.go
go.mod Add stopwatch Feb 26, 2019
go.sum create separate examples folder and ensure hrtime is not a hard depen… Feb 18, 2019
histogram.go fix missing comments Feb 26, 2019
histogram_bounds.go fix special case of value truncation Apr 4, 2019
histogram_bounds_test.go fix special case of value truncation Apr 4, 2019
init.go fix typo Feb 26, 2019
now.go add missing comments Oct 1, 2018
now_other.go
now_test.go add benchmarks for timing functions Apr 30, 2018
now_windows.go describe hrtime.Now more in depth Feb 26, 2019
stopwatch.go make stopwatch implement hrplot.Benchmark interface Apr 2, 2019
stopwatch_test.go simplify stopwatch Start/Stop usage Feb 26, 2019
stopwatchtsc.go make stopwatch implement hrplot.Benchmark interface Apr 2, 2019
tsc.go add missing comments Oct 1, 2018
tsc_amd64.go improve comments about tsc support Feb 18, 2019
tsc_amd64.s fix cpuidAsm declaration Feb 26, 2019
tsc_internal_test.go
tsc_other.go improve comments about tsc support Feb 18, 2019
tsc_test.go add benchmarks for timing functions Apr 30, 2018

README.md

hrtime

GoDoc

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.

Example

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.

Benchmarking

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)
	}
}
You can’t perform that action at this time.