Skip to content
Open
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
52 changes: 41 additions & 11 deletions node/bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package node

import (
"fmt"
"math"
"math/rand"
"testing"

Expand Down Expand Up @@ -95,21 +96,50 @@ func BenchmarkOr(b *testing.B) {
}
}

// BenchmarkAnd traverses AND of two static asc leaves over LID sets of different density
func BenchmarkAnd(b *testing.B) {
sizes := []int{1000, 10_000, 1_000_000}
densities := []struct {
name string
k func(size int) int
}{
{"random", nil},
{"dense", func(size int) int { return 2 }},
{"medium", func(size int) int { return int(math.Sqrt(float64(size))) }},
{"sparse", func(size int) int { return size / 64 }},
}

for _, s := range sizes {
b.Run(fmt.Sprintf("size=%d", s), func(b *testing.B) {
r := rand.New(rand.NewSource(benchRandSeed))
res := make([]uint32, 0, s)
n := NewAnd(newNodeStaticSize(r, s), newNodeStaticSize(r, s))

for b.Loop() {
res = readAllInto(n, res)
}

assert.Equal(b, cap(res), s)
})
for _, d := range densities {
b.Run(fmt.Sprintf("size=%d/density=%s", s, d.name), func(b *testing.B) {
r := rand.New(rand.NewSource(benchRandSeed))
dataA, _ := Generate(r, s)
var dataB []uint32
if d.k != nil {
k := d.k(s)
dataB = make([]uint32, 0, s/k+1)
for i := 0; i < len(dataA); i += k {
dataB = append(dataB, dataA[i])
}
} else {
dataB, _ = Generate(r, s)
}

// control run: the intersection must be exactly dataB
want := readAllIntoGeq(NewAnd(NewStatic(dataA, true), NewStatic(dataB, true)), nil)
if d.k != nil {
assert.Equal(b, len(dataB), len(want))
}

res := make([]uint32, 0, s)
for b.Loop() {
n := NewAnd(NewStatic(dataA, true), NewStatic(dataB, true))
res = readAllInto(n, res[:0])
}
assert.Equal(b, len(want), len(res))
b.ReportMetric(float64(b.Elapsed().Nanoseconds())/float64(b.N*len(want)), "ns/match")
})
}
}
}

Expand Down
5 changes: 2 additions & 3 deletions node/node_static.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package node

import (
"math"
"sort"
)

type staticCursor struct {
Expand Down Expand Up @@ -54,7 +53,7 @@ func (n *staticAsc) NextGeq(nextID LID) LID {
}

from := n.ptr
idx := sort.Search(len(n.data)-from, func(i int) bool { return n.data[from+i] >= nextID.Unpack() })
idx := searchGeqGallopAsc(n.data[from:], nextID.Unpack())
if idx >= len(n.data)-from {
return NullLID()
}
Expand All @@ -79,7 +78,7 @@ func (n *staticDesc) NextGeq(nextID LID) LID {
if n.ptr < 0 {
return NullLID()
}
idx := sort.Search(n.ptr+1, func(i int) bool { return n.data[i] > nextID.Unpack() }) - 1
idx := searchGtGallopDesc(n.data[:n.ptr+1], nextID.Unpack()) - 1
if idx < 0 {
return NullLID()
}
Expand Down
Loading