gcs: ensure benchmarks aren't optimized away by the compiler

This commit modifies the benchmarks a bit to ensure that the
computations themselves aren’t optimized away. We do this by binding
each variable to a local variable, and them ultimately a variable at
the package level scope.
This commit is contained in:
Olaoluwa Osuntokun 2017-06-08 17:46:02 -07:00
parent 5a770ec85e
commit e87fef40f3

View file

@ -13,38 +13,96 @@ import (
"github.com/btcsuite/btcutil/gcs" "github.com/btcsuite/btcutil/gcs"
) )
func genRandFilterElements(numElements uint) ([][]byte, error) {
testContents := make([][]byte, numElements)
for i := range contents {
randElem := make([]byte, 32)
if _, err := rand.Read(randElem); err != nil {
return nil, err
}
testContents[i] = randElem
}
return testContents, nil
}
var (
generatedFilter *gcs.Filter
filterErr error
)
// BenchmarkGCSFilterBuild benchmarks building a filter. // BenchmarkGCSFilterBuild benchmarks building a filter.
func BenchmarkGCSFilterBuild(b *testing.B) { func BenchmarkGCSFilterBuild50000(b *testing.B) {
b.StopTimer() b.StopTimer()
var testKey [gcs.KeySize]byte
for i := 0; i < gcs.KeySize; i += 4 { for i := 0; i < gcs.KeySize; i += 4 {
binary.BigEndian.PutUint32(key[i:], rand.Uint32()) binary.BigEndian.PutUint32(testKey[i:], rand.Uint32())
}
randFilterElems, genErr := genRandFilterElements(50000)
if err != nil {
b.Fatalf("unable to generate random item: %v", genErr)
} }
b.StartTimer() b.StartTimer()
var localFilter *gcs.Filter
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
gcs.BuildGCSFilter(P, key, contents) localFilter, err = gcs.BuildGCSFilter(P, key,
randFilterElems)
if err != nil {
b.Fatalf("unable to generate filter: %v", err)
} }
} }
generatedFilter = localFilter
}
var (
match bool
)
// BenchmarkGCSFilterMatch benchmarks querying a filter for a single value. // BenchmarkGCSFilterMatch benchmarks querying a filter for a single value.
func BenchmarkGCSFilterMatch(b *testing.B) { func BenchmarkGCSFilterMatch(b *testing.B) {
b.StopTimer() b.StopTimer()
filter, err = gcs.BuildGCSFilter(P, key, contents) filter, err := gcs.BuildGCSFilter(P, key, contents)
if err != nil { if err != nil {
b.Errorf("Failed to build filter") b.Fatalf("Failed to build filter")
} }
b.StartTimer() b.StartTimer()
var (
localMatch bool
)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
filter.Match(key, []byte("Nate")) localMatch, err = filter.Match(key, []byte("Nate"))
filter.Match(key, []byte("Nates")) if err != nil {
b.Fatalf("unable to match filter: %v", err)
} }
localMatch, err = filter.Match(key, []byte("Nates"))
if err != nil {
b.Fatalf("unable to match filter: %v", err)
}
}
match = localMatch
} }
// BenchmarkGCSFilterMatchAny benchmarks querying a filter for a list of // BenchmarkGCSFilterMatchAny benchmarks querying a filter for a list of
// values. // values.
func BenchmarkGCSFilterMatchAny(b *testing.B) { func BenchmarkGCSFilterMatchAny(b *testing.B) {
b.StopTimer()
filter, err := gcs.BuildGCSFilter(P, key, contents)
if err != nil {
b.Fatalf("Failed to build filter")
}
b.StartTimer()
var (
localMatch bool
)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
filter.MatchAny(key, contents2) localMatch, err = filter.MatchAny(key, contents2)
if err != nil {
b.Fatalf("unable to match filter: %v", err)
} }
} }
match = localMatch
}