Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/continuous-benchmarks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 2 additions & 0 deletions cache/cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ func TestStress(t *testing.T) {
}

func BenchmarkBucketClean(b *testing.B) {
b.SkipNow()

b.StopTimer()

cleaner := NewCleaner(0, nil)
Expand Down
4 changes: 4 additions & 0 deletions frac/active_ids_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand All @@ -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++ {
Expand Down
21 changes: 6 additions & 15 deletions indexer/processor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,29 +89,20 @@
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)

Check failure on line 93 in indexer/processor_test.go

View workflow job for this annotation

GitHub Actions / lint

Error return value of `time.Parse` is not checked (errcheck)
}
})

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)

Check failure on line 105 in indexer/processor_test.go

View workflow job for this annotation

GitHub Actions / lint

Error return value of `time.Parse` is not checked (errcheck)
}
})
}
Expand Down
213 changes: 140 additions & 73 deletions node/bench_test.go
Original file line number Diff line number Diff line change
@@ -1,131 +1,198 @@
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
}

// 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
}
}

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))
}
}
19 changes: 12 additions & 7 deletions node/node_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
4 changes: 4 additions & 0 deletions pattern/pattern_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,8 @@ func TestFindSequence(t *testing.T) {
}

func BenchmarkFindSequence_Deterministic(b *testing.B) {
b.SkipNow()

type testCase struct {
haystack []byte
needles [][]byte
Expand Down Expand Up @@ -556,6 +558,8 @@ func BenchmarkFindSequence_Deterministic(b *testing.B) {
}

func BenchmarkFindSequence_Random(b *testing.B) {
b.SkipNow()

sizes := []struct {
name string
haystackSize int
Expand Down
Loading
Loading