mirror of
https://github.com/pkg/errors.git
synced 2025-05-04 22:49:58 +00:00
toperr is not used, but the go compiler itself doesn't detect this because it's within an anonymous function. However, go/types does detect this as being unused, which causes any static analysis tools which uses go/types' type checker to fail with the message "toperr assigned and not used". The final result of the benchmarked function is instead assigned to an exported global variable to ensure the compiler cannot now, nor in the future optimise away the function calls due to no observable side effects. It was chosen to assign the final result, after the benchmark loop, to the global variable, as this best follows the example set in the CL https://go-review.googlesource.com/#/c/37195/. As opposed to having each call to f assign to the global. This also appears to better align with the original author's intention of toperr. This change had no observable impact on the benchmark. Related https://github.com/golang/go/issues/3059. Related https://github.com/golang/go/issues/8560. Thanks dominikh for additional clarifications.
64 lines
1.0 KiB
Go
64 lines
1.0 KiB
Go
// +build go1.7
|
|
|
|
package errors
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
|
|
stderrors "errors"
|
|
)
|
|
|
|
func noErrors(at, depth int) error {
|
|
if at >= depth {
|
|
return stderrors.New("no error")
|
|
}
|
|
return noErrors(at+1, depth)
|
|
}
|
|
|
|
func yesErrors(at, depth int) error {
|
|
if at >= depth {
|
|
return New("ye error")
|
|
}
|
|
return yesErrors(at+1, depth)
|
|
}
|
|
|
|
// GlobalE is an exported global to store the result of benchmark results,
|
|
// preventing the compiler from optimising the benchmark functions away.
|
|
var GlobalE error
|
|
|
|
func BenchmarkErrors(b *testing.B) {
|
|
type run struct {
|
|
stack int
|
|
std bool
|
|
}
|
|
runs := []run{
|
|
{10, false},
|
|
{10, true},
|
|
{100, false},
|
|
{100, true},
|
|
{1000, false},
|
|
{1000, true},
|
|
}
|
|
for _, r := range runs {
|
|
part := "pkg/errors"
|
|
if r.std {
|
|
part = "errors"
|
|
}
|
|
name := fmt.Sprintf("%s-stack-%d", part, r.stack)
|
|
b.Run(name, func(b *testing.B) {
|
|
var err error
|
|
f := yesErrors
|
|
if r.std {
|
|
f = noErrors
|
|
}
|
|
b.ReportAllocs()
|
|
for i := 0; i < b.N; i++ {
|
|
err = f(0, r.stack)
|
|
}
|
|
b.StopTimer()
|
|
GlobalE = err
|
|
})
|
|
}
|
|
}
|