Skip to content

Commit

Permalink
all: add initial implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
changkun committed Nov 7, 2020
1 parent 35d507a commit 57faf66
Show file tree
Hide file tree
Showing 35 changed files with 4,653 additions and 1 deletion.
124 changes: 123 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,124 @@
# bench
refined performance measurement in Go

Reliable performance measurement for Go programs. All in one design.

```
$ go get golang.design/x/bench
```

## Features

- Combine [benchstat](https://pkg.go.dev/golang.org/x/perf/cmd/benchstat), [perflock](https://github.com/aclements/perflock) and more...
- Short command and only run benchmarks
- Automatic performance locking for benchmarks
- Automatic statistic analysis for benchmark results
- Color indications for benchmark results

## Usage

### Enable `bench` Daemon (optional, Linux only)

```sh
$ cd $GOPATH/src/golang.design/x/bench
$ ./install.bash
```

If your init system is supported, this will also configure `bench` to start automatically on boot.

Or you can install and run `bench` daemon manually:

```sh
$ sudo install $GOPATH/bin/bench /usr/bin/bench
$ sudo -b bench -daemon
```

### Default Behavior

```sh
$ bench
```

The detault behavior of `bench` run benchmarks under your current
working directory, and each benchmark will be ran 10 times for further
statistical analysis. It will also try to acquire performance lock from
`bench` daemon to gain more stable results. Furthermore, the benchmark
results are saved as a text file to the working directory and named as
`<timestamp>.txt`.

Example:

```
$ cd example
$ bench
bench: run benchmarks under 90% cpufreq...
bench: go test -run=^$ -bench=. -count=10
goos: linux
goarch: amd64
pkg: golang.design/x/bench/example
BenchmarkDemo-16 21114 57340 ns/op
...
BenchmarkDemo-16 21004 57097 ns/op
PASS
ok golang.design/x/bench/example 17.791s
bench: results are saved to file: ./bench-2020-11-07-19:59:51.txt
name time/op
Demo-16 57.0µs ±1%
$ # ... do some changes to the benchmark ...
$ bench
bench: run benchmarks under 90% cpufreq...
bench: go test -run=^$ -bench=. -count=10
goos: linux
goarch: amd64
pkg: golang.design/x/bench/example
BenchmarkDemo-16 213145 5625 ns/op
...
BenchmarkDemo-16 212959 5632 ns/op
PASS
ok golang.design/x/bench/example 12.536s
bench: results are saved to file: ./bench-2020-11-07-20:00:16.txt
name time/op
Demo-16 5.63µs ±0%
$ bench bench-2020-11-07-19:59:51.txt bench-2020-11-07-20:00:16.txt
name old time/op new time/op delta
Demo-16 57.0µs ±1% 5.6µs ±0% -90.13% (p=0.000 n=10+8)
```

### Options

Options for checking daemon status:

```sh
bench -list
```

Options for statistic tests:

```sh
bench old.txt [new.txt] # same from benchstat
bench -delta-test
bench -alpha
bench -geomean
bench -split
bench -sort
```

Options for running benchmarks:

```sh
bench -v # enable verbose outputs
bench -shared # enable shared execution
bench -cpufreq 90 # cpu frequency (default: 90)
bench -name BenchmarkXXX # go test `-bench` flag (default: .)
bench -count 20 # go test `-count` flag (default: 10)
bench -time 100x # go test `-benchtime` flag (default: unset)
bench -cpuproc 1,2,4,8,16,32,128 # go test `-cpu` flag (default: unset)
```

## License

&copy; 2020 The golang.design Authors
15 changes: 15 additions & 0 deletions example/bench-2020-11-07-19:59:51.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
goos: linux
goarch: amd64
pkg: golang.design/x/bench/example
BenchmarkDemo-16 21114 57340 ns/op
BenchmarkDemo-16 21109 56897 ns/op
BenchmarkDemo-16 21091 56833 ns/op
BenchmarkDemo-16 21121 56821 ns/op
BenchmarkDemo-16 21105 56953 ns/op
BenchmarkDemo-16 21112 56830 ns/op
BenchmarkDemo-16 20836 57499 ns/op
BenchmarkDemo-16 21084 56885 ns/op
BenchmarkDemo-16 20990 57245 ns/op
BenchmarkDemo-16 21004 57097 ns/op
PASS
ok golang.design/x/bench/example 17.791s
15 changes: 15 additions & 0 deletions example/bench-2020-11-07-20:00:16.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
goos: linux
goarch: amd64
pkg: golang.design/x/bench/example
BenchmarkDemo-16 213145 5625 ns/op
BenchmarkDemo-16 211988 5629 ns/op
BenchmarkDemo-16 211838 5629 ns/op
BenchmarkDemo-16 212151 5627 ns/op
BenchmarkDemo-16 212577 5627 ns/op
BenchmarkDemo-16 210150 5635 ns/op
BenchmarkDemo-16 212650 5637 ns/op
BenchmarkDemo-16 210063 5670 ns/op
BenchmarkDemo-16 212568 5665 ns/op
BenchmarkDemo-16 212959 5632 ns/op
PASS
ok golang.design/x/bench/example 12.536s
19 changes: 19 additions & 0 deletions example/bench_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright 2020 The golang.design Initiative Authors.
// All rights reserved. Use of this source code is governed
// by a GNU GPLv3 license that can be found in the LICENSE file.

package example

import "testing"

func grow(n int) {
if n > 0 {
grow(n - 1)
}
}

func BenchmarkDemo(b *testing.B) {
for i := 0; i < b.N; i++ {
grow(10000) // try change this and re-run `bench`
}
}
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module golang.design/x/bench

go 1.15
6 changes: 6 additions & 0 deletions init/systemd/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
To configure systemd to run `bench`, run

```
$ sudo install -m 0644 bench.service /etc/systemd/system
$ sudo systemctl enable --now bench.service
```
10 changes: 10 additions & 0 deletions init/systemd/bench.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[Unit]
Description=Bench daemon

[Service]
Type=simple
ExecStart=/usr/bin/bench -daemon
Restart=on-failure

[Install]
WantedBy=multi-user.target
6 changes: 6 additions & 0 deletions init/upstart/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
To configure Upstart to run `bench`, copy `bench.conf` into `/etc/init/` and run sudo start `bench`. E.g.,

```sh
$ sudo install -m 0644 bench.conf /etc/init/
$ sudo start bench
```
11 changes: 11 additions & 0 deletions init/upstart/bench.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# bench - Benchmark performance locking service

description "bench daemon"

start on runlevel [2345]
stop on runlevel [!2345]
respawn

console log

exec bench -daemon
40 changes: 40 additions & 0 deletions install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#!/bin/bash

set -e

BINPATH="$(go env GOBIN)"
if [[ -z "$BINPATH" ]]; then
BINPATH="$(go env GOPATH)/bin"
fi
BIN="$BINPATH/bench"
if [[ ! -x "$BIN" ]]; then
echo "bench binary $BIN does not exist." 2>&1
echo "Please run go install golang.design/x/bench" 2>&1
exit 1
fi

echo "Installing $BIN to /usr/bin" 1>&2
sudo install "$BIN" /usr/bin/bench

start="-b /usr/bin/bench -daemon"
starttype=
if [[ -d /etc/init ]]; then
echo "Installing init script for Upstart" 1>&2
sudo install -m 0644 init/upstart/bench.conf /etc/init/
start="service bench start"
starttype=" (using Upstart)"
fi
if [[ -d /etc/systemd ]]; then
echo "Installing service for systemd" 1>&2
sudo install -m 0644 init/systemd/bench.service /etc/systemd/system
sudo systemctl enable --quiet bench.service
start="systemctl start bench.service"
starttype=" (using systemd)"
fi

if /usr/bin/bench -list >/dev/null 2>&1; then
echo "Not starting bench daemon (already running)" 1>&2
else
echo "Starting bench daemon$starttype" 1>&2
sudo $start
fi
Loading

0 comments on commit 57faf66

Please sign in to comment.