diff --git a/.github/workflows/continuous-benchmarks.yml b/.github/workflows/continuous-benchmarks.yml index f40c5e66..78e3a768 100644 --- a/.github/workflows/continuous-benchmarks.yml +++ b/.github/workflows/continuous-benchmarks.yml @@ -28,7 +28,7 @@ jobs: - name: Run Golang benchmarks shell: bash run: | - COUNT=$([[ "${{ github.event_name }}" == "pull_request" ]] && echo 1 || echo 5) + COUNT=$([[ "${{ github.event_name }}" == "pull_request" ]] && echo 5 || echo 5) LOG_LEVEL=FATAL GOMAXPROCS=4 go test -run='$^' -count=$COUNT -bench=. -benchmem ./... | tee ${{ runner.temp }}/gotool.txt # Add GitHub job summary for pull requests. diff --git a/cache/cache_test.go b/cache/cache_test.go index 8ef40be9..52979647 100644 --- a/cache/cache_test.go +++ b/cache/cache_test.go @@ -129,6 +129,8 @@ func TestStress(t *testing.T) { } func BenchmarkBucketClean(b *testing.B) { + b.SkipNow() + b.StopTimer() cleaner := NewCleaner(0, nil) diff --git a/frac/active_ids_test.go b/frac/active_ids_test.go index ae2f6111..a07a4cfe 100644 --- a/frac/active_ids_test.go +++ b/frac/active_ids_test.go @@ -33,6 +33,8 @@ func TestSeqListAppend(t *testing.T) { } func BenchmarkMutexListAppend(b *testing.B) { + b.SkipNow() + gr := 2 mu := sync.Mutex{} b.SetBytes(int64(gr * 8000000)) @@ -57,6 +59,8 @@ func BenchmarkMutexListAppend(b *testing.B) { } func BenchmarkSeqListAppend(b *testing.B) { + b.SkipNow() + gr := 2 b.SetBytes(int64(gr * 8000000)) for n := 0; n < b.N; n++ { diff --git a/indexer/processor_test.go b/indexer/processor_test.go index 0b25c5f3..485153d5 100644 --- a/indexer/processor_test.go +++ b/indexer/processor_test.go @@ -89,29 +89,20 @@ func BenchmarkParseESTime(b *testing.B) { const toParseRFC3339 = "2024-04-19T18:04:25.999Z" b.Run("es_stdlib", func(b *testing.B) { - for i := 0; i < b.N; i++ { - _, err := time.Parse(consts.ESTimeFormat, toParse) - if err != nil { - b.Fatal(err) - } + for b.Loop() { + time.Parse(consts.ESTimeFormat, toParse) } }) b.Run("handwritten", func(b *testing.B) { - for i := 0; i < b.N; i++ { - _, ok := parseESTime(toParse) - if !ok { - b.Fatal() - } + for b.Loop() { + parseESTime(toParse) } }) b.Run("rfc3339", func(b *testing.B) { - for i := 0; i < b.N; i++ { - _, err := time.Parse(time.RFC3339, toParseRFC3339) - if err != nil { - b.Fatal(err) - } + for b.Loop() { + time.Parse(time.RFC3339, toParseRFC3339) } }) } diff --git a/node/bench_test.go b/node/bench_test.go index d16e50e6..5ad53664 100644 --- a/node/bench_test.go +++ b/node/bench_test.go @@ -1,23 +1,24 @@ package node import ( - "math/rand" + "fmt" "testing" - - "github.com/stretchr/testify/assert" + "time" ) -func newNodeStaticSize(size int) *staticAsc { - data, _ := Generate(size) - return &staticAsc{staticCursor: staticCursor{data: data}} -} +var ( + // Setup dataset size and data itself. + lidsCount uint32 = 100_000 + // lids is a sorted slice [1; 1 + lidsCount); + lids, last = generate(lidsCount) +) -func Generate(n int) ([]uint32, uint32) { +func generate(n uint32) ([]uint32, uint32) { v := make([]uint32, n) last := uint32(1) for i := 0; i < len(v); i++ { v[i] = last - last += uint32(1 + rand.Intn(5)) + last += 1 } return v, last } @@ -25,16 +26,20 @@ func Generate(n int) ([]uint32, uint32) { // bench for base point // you can't go faster func BenchmarkCopy(b *testing.B) { + b.SkipNow() + res := make([]uint32, b.N) - n := newNodeStaticSize(b.N) + var n *staticAsc = nil b.ResetTimer() copy(res, n.data) } // base point func BenchmarkIterate(b *testing.B) { + b.SkipNow() + res := make([]uint32, b.N) - n := newNodeStaticSize(b.N) + var n *staticAsc = nil b.ResetTimer() for i, v := range n.data { res[i] = v @@ -42,90 +47,152 @@ func BenchmarkIterate(b *testing.B) { } func BenchmarkStatic(b *testing.B) { - res := make([]uint32, 0, b.N) - n := newNodeStaticSize(b.N) - b.ResetTimer() - res = readAllInto(n, res) - assert.Equal(b, cap(res), b.N) + b.Run("asc", func(b *testing.B) { + for b.Loop() { + b.StopTimer() + n := NewStatic(lids, false) + b.StartTimer() + + all(n) + } + }) + + b.Run("desc", func(b *testing.B) { + for b.Loop() { + b.StopTimer() + n := NewStatic(lids, true) + b.StartTimer() + + all(n) + } + }) } func BenchmarkNot(b *testing.B) { - v, last := Generate(b.N) - res := make([]uint32, 0, last+1) - n := NewNot(NewStatic(v, false), 1, last, false) - b.ResetTimer() - res = readAllInto(n, res) - assert.Equal(b, cap(res), int(last)+1) + for b.Loop() { + b.StopTimer() + n := NewNot( + NewStatic(lids, false), + 1, last, false, + ) + b.StartTimer() + + all(n) + } } func BenchmarkNotEmpty(b *testing.B) { - res := make([]uint32, 0, b.N*2) - n := NewNot(NewStatic(nil, false), 1, uint32(b.N), false) - b.ResetTimer() - res = readAllInto(n, res) - assert.Equal(b, cap(res), b.N*2) + for b.Loop() { + b.StopTimer() + n := NewNot( + NewStatic(nil, false), + 1, uint32(lidsCount), false, + ) + b.StartTimer() + + all(n) + } } func BenchmarkOr(b *testing.B) { - res := make([]uint32, 0, b.N*2) - n := NewOr(newNodeStaticSize(b.N), newNodeStaticSize(b.N), false) - b.ResetTimer() - res = readAllInto(n, res) - assert.Equal(b, cap(res), b.N*2) + for b.Loop() { + b.StopTimer() + n := NewOr( + NewStatic(lids, false), + NewStatic(lids, false), + false, + ) + b.StartTimer() + + all(n) + } } func BenchmarkAnd(b *testing.B) { - res := make([]uint32, 0, b.N) - n := NewAnd(newNodeStaticSize(b.N), newNodeStaticSize(b.N), false) - b.ResetTimer() - res = readAllInto(n, res) - assert.Equal(b, cap(res), b.N) + for b.Loop() { + b.StopTimer() + n := NewAnd( + NewStatic(lids, false), + NewStatic(lids, false), + false, + ) + b.StartTimer() + + all(n) + } } func BenchmarkNAnd(b *testing.B) { - res := make([]uint32, 0, b.N) - n := NewNAnd(newNodeStaticSize(b.N), newNodeStaticSize(b.N), false) - b.ResetTimer() - res = readAllInto(n, res) - assert.Equal(b, cap(res), b.N) + for b.Loop() { + b.StopTimer() + n := NewNAnd( + NewStatic(lids, false), + NewStatic(lids, false), + false, + ) + b.StartTimer() + + all(n) + } } func BenchmarkAndTree(b *testing.B) { - n1 := NewAnd(newNodeStaticSize(b.N), newNodeStaticSize(b.N), false) - n2 := NewAnd(newNodeStaticSize(b.N), newNodeStaticSize(b.N), false) - n3 := NewAnd(newNodeStaticSize(b.N), newNodeStaticSize(b.N), false) - n4 := NewAnd(newNodeStaticSize(b.N), newNodeStaticSize(b.N), false) - n12 := NewAnd(n1, n2, false) - n34 := NewAnd(n3, n4, false) - n := NewAnd(n12, n34, false) - res := make([]uint32, 0, b.N) - b.ResetTimer() - res = readAllInto(n, res) - assert.Equal(b, cap(res), b.N) + for b.Loop() { + b.StopTimer() + + n1 := NewAnd(NewStatic(lids, false), NewStatic(lids, false), false) + n2 := NewAnd(NewStatic(lids, false), NewStatic(lids, false), false) + n3 := NewAnd(NewStatic(lids, false), NewStatic(lids, false), false) + n4 := NewAnd(NewStatic(lids, false), NewStatic(lids, false), false) + + n12 := NewAnd(n1, n2, false) + n34 := NewAnd(n3, n4, false) + + n := NewAnd(n12, n34, false) + b.StartTimer() + + all(n) + } } func BenchmarkOrTree(b *testing.B) { - n1 := NewOr(newNodeStaticSize(b.N), newNodeStaticSize(b.N), false) - n2 := NewOr(newNodeStaticSize(b.N), newNodeStaticSize(b.N), false) - n3 := NewOr(newNodeStaticSize(b.N), newNodeStaticSize(b.N), false) - n4 := NewOr(newNodeStaticSize(b.N), newNodeStaticSize(b.N), false) - n12 := NewOr(n1, n2, false) - n34 := NewOr(n3, n4, false) - n := NewOr(n12, n34, false) - res := make([]uint32, 0, b.N*8) - b.ResetTimer() - res = readAllInto(n, res) - assert.Equal(b, cap(res), b.N*8) + for b.Loop() { + b.StopTimer() + + n1 := NewOr(NewStatic(lids, false), NewStatic(lids, false), false) + n2 := NewOr(NewStatic(lids, false), NewStatic(lids, false), false) + n3 := NewOr(NewStatic(lids, false), NewStatic(lids, false), false) + n4 := NewOr(NewStatic(lids, false), NewStatic(lids, false), false) + + n12 := NewOr(n1, n2, false) + n34 := NewOr(n3, n4, false) + + n := NewOr(n12, n34, false) + b.StartTimer() + + all(n) + } } +// FIXME(dkharms): What is wrong here? +// One iteration finishes in 20ns - that's impossible. func BenchmarkComplex(b *testing.B) { - res := make([]uint32, 0, b.N*2) - n1 := NewAnd(newNodeStaticSize(b.N), newNodeStaticSize(b.N), false) - n2 := NewOr(newNodeStaticSize(b.N), newNodeStaticSize(b.N), false) - n3 := NewNAnd(newNodeStaticSize(b.N), newNodeStaticSize(b.N), false) - n12 := NewOr(n1, n2, false) - n := NewAnd(n12, n3, false) - b.ResetTimer() - res = readAllInto(n, res) - assert.Equal(b, cap(res), b.N*2) + b.SkipNow() + + for b.Loop() { + b.StopTimer() + + n1 := NewAnd(NewStatic(lids, false), NewStatic(lids, false), false) + n2 := NewOr(NewStatic(lids, false), NewStatic(lids, false), false) + n3 := NewNAnd(NewStatic(lids, false), NewStatic(lids, false), false) + + n12 := NewOr(n1, n2, false) + + n := NewAnd(n12, n3, false) + b.StartTimer() + + start := time.Now() + all(n) + fmt.Printf("time.Since(start): %v\n", time.Since(start)) + } } diff --git a/node/node_test.go b/node/node_test.go index 6da2d8a1..4eb3f399 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -7,17 +7,22 @@ import ( "github.com/stretchr/testify/require" ) -func readAllInto(node Node, ids []uint32) []uint32 { - id, has := node.Next() +func all(node Node) { + _, has := node.Next() for has { - ids = append(ids, id) - id, has = node.Next() + _, has = node.Next() } - return ids } -func readAll(node Node) []uint32 { - return readAllInto(node, nil) +func readAll(node Node) (lids []uint32) { + v, has := node.Next() + + for has { + lids = append(lids, v) + v, has = node.Next() + } + + return lids } func getRemainingSlice(t *testing.T, node Node) []uint32 { diff --git a/pattern/pattern_test.go b/pattern/pattern_test.go index 2c9a5702..2597c7dc 100644 --- a/pattern/pattern_test.go +++ b/pattern/pattern_test.go @@ -515,6 +515,8 @@ func TestFindSequence(t *testing.T) { } func BenchmarkFindSequence_Deterministic(b *testing.B) { + b.SkipNow() + type testCase struct { haystack []byte needles [][]byte @@ -556,6 +558,8 @@ func BenchmarkFindSequence_Deterministic(b *testing.B) { } func BenchmarkFindSequence_Random(b *testing.B) { + b.SkipNow() + sizes := []struct { name string haystackSize int diff --git a/tests/setup/doc_test.go b/tests/setup/doc_test.go index bf463de1..4107921a 100644 --- a/tests/setup/doc_test.go +++ b/tests/setup/doc_test.go @@ -55,6 +55,8 @@ func RunParallel(n int, f func()) { } func BenchmarkRandomJSON(b *testing.B) { + b.SkipNow() + RunParallel(4, func() { sum := 0 for i := 0; i < b.N; i++ { @@ -67,6 +69,8 @@ func BenchmarkRandomJSON(b *testing.B) { } func BenchmarkRandomDoc(b *testing.B) { + b.SkipNow() + RunParallel(4, func() { sum := 0 for i := 0; i < b.N; i++ { @@ -79,6 +83,8 @@ func BenchmarkRandomDoc(b *testing.B) { } func BenchmarkGenerateDocs(b *testing.B) { + b.SkipNow() + res := GenerateDocs(b.N, func(_ int, doc *ExampleDoc) { *doc = *RandomDoc(1) }) @@ -86,11 +92,15 @@ func BenchmarkGenerateDocs(b *testing.B) { } func BenchmarkGenerateDocsJSON(b *testing.B) { + b.SkipNow() + res := GenerateDocsJSON(b.N, false) _ = res } func BenchmarkGenerateDocsJSONFields(b *testing.B) { + b.SkipNow() + res := GenerateDocsJSON(b.N, true) _ = res }