05/07/2020 - GO
In golang applications, you can use bench
command to run benchmark tests and see performance results. You can also use benchstat or benchcmp commands to compare past results to new ones. In example below, we are going to use two different functions to validate yyy-mm-dd
format and write benchmark tests for both. I suggest you to read a very valuable High Performance Go Workshop post.
// All benchmarks in the project
go test -v -bench=. -benchmem ./...
go test -v -bench=. ./... -benchmem
// All benchmarks in the package
go test -v -bench=. -benchmem ./internal/validator/
// internal/validator/datetime.go
package validator
import (
"regexp"
"time"
)
// DateRegex validates date format `yyyy-mm-dd`.
func DateRegex(v string) bool {
return regexp.MustCompile(`([12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01]))`).MatchString(v)
}
// TimeParse validates date format `yyyy-mm-dd`.
func TimeParse(v string) bool {
if _ , e := time.Parse("2006-01-02", v); e != nil {
return false
}
return true
}
// internal/validator/datetime_test.go
package validator
import (
"testing"
)
func BenchmarkDateRegex(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = DateRegex("2020-01-01")
}
}
func BenchmarkTimeParse(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = TimeParse("2020-01-01")
}
}
$ go test -v -bench=. -benchmem ./internal/validator/
BenchmarkDateRegex-4 133645 8860 ns/op 7047 B/op 62 allocs/op
BenchmarkTimeParse-4 7844908 150 ns/op 0 B/op 0 allocs/op
// internal/validator/datetime_test.go
package validator
import (
"testing"
)
func benchmarkDateRegex(v string, b *testing.B) {
for i := 0; i < b.N; i++ {
_ = DateRegex(v)
}
}
func BenchmarkDateRegex_1(b *testing.B) { benchmarkDateRegex("", b) }
func BenchmarkDateRegex_2(b *testing.B) { benchmarkDateRegex(" ", b) }
func BenchmarkDateRegex_3(b *testing.B) { benchmarkDateRegex("2020-01-01", b) }
$ go test -v -bench=. -benchmem ./internal/validator/
BenchmarkDateRegex_1-4 122085 8483 ns/op 7032 B/op 62 allocs/op
BenchmarkDateRegex_2-4 132746 8445 ns/op 7032 B/op 62 allocs/op
BenchmarkDateRegex_3-4 132991 8802 ns/op 7048 B/op 62 allocs/op
Here we are comparing past results to current results. Make sure you run go get golang.org/x/perf/cmd/benchstat
and go get golang.org/x/tools/cmd/benchcmp
to install packages.
$ go test -v -bench=. -benchmem ./internal/validator/ > old.out
// Do some changes to your code
$ go test -v -bench=. -benchmem ./internal/validator/ > new.out
$ benchstat old.out new.out
name old time/op new time/op delta
DateRegex-4 8.98µs ± 0% 8.75µs ± 0% ~ (p=1.000 n=1+1)
TimeParse-4 151ns ± 0% 152ns ± 0% ~ (p=1.000 n=1+1)
name old alloc/op new alloc/op delta
DateRegex-4 7.05kB ± 0% 7.05kB ± 0% ~ (p=1.000 n=1+1)
TimeParse-4 0.00B 0.00B ~ (all equal)
name old allocs/op new allocs/op delta
DateRegex-4 62.0 ± 0% 62.0 ± 0% ~ (all equal)
TimeParse-4 0.00 0.00 ~ (all equal)
$ benchcmp old.out new.out
benchmark old ns/op new ns/op delta
BenchmarkDateRegex-4 8978 8752 -2.52%
BenchmarkTimeParse-4 151 152 +0.66%
benchmark old allocs new allocs delta
BenchmarkDateRegex-4 62 62 +0.00%
BenchmarkTimeParse-4 0 0 +0.00%
benchmark old bytes new bytes delta
BenchmarkDateRegex-4 7052 7046 -0.09%
BenchmarkTimeParse-4 0 0 +0.00%