til/Development/Go/testing.md

86 lines
1.4 KiB
Markdown

# [testing](https://golang.org/pkg/testing/)
## Benchmark
Any benchmark should be careful to prevent **compiler optimization**.
Example `calc.go` in package `calc`:
```go
package calc
import (
"time"
)
var input float64
func init() {
if time.Now().Year() > 1900 {
input = 426942694269
}
}
func calc() int {
x := input
x /= 6.9
x /= 4.2
x /= 6.9
x /= 4.2
return int(x)
}
```
Example `calc_test.go` in package `calc`:
```go
package calc
import (
"runtime"
"testing"
)
func BenchmarkX(b *testing.B) {
for i := 0; i < b.N; i++ {
calc()
}
}
var sink int
func BenchmarkCalcSink(b *testing.B) {
var result int
for i := 0; i < b.N; i++ {
result = calc()
}
// prevent compiler optimization
sink = result
}
func BenchmarkCalcKeepAlive(b *testing.B) {
for i := 0; i < b.N; i++ {
result := calc()
// prevent compiler optimization
runtime.KeepAlive(result)
}
}
```
Benchmark result when run with `go test -bench=.`
```txt
goos: linux
goarch: amd64
BenchmarkCalc-4 1000000000 0.343 ns/op
BenchmarkCalcSink-4 229652618 5.30 ns/op
BenchmarkCalcKeepAlive-4 225297381 5.27 ns/op
```
`BenchmarkCalc` is fast because it has compiler optimization.
There are 2 methods for preventing compiler optimization:
sink (`BenchmarkCalcSink`) or keep alive (`BenchmarkCalcKeepAlive`).