Skip to content

Commit 5251f1b

Browse files
AskAlexSharovclaude
andcommitted
roaring64: port stack-allocated iterator benchmarks from bitmap32
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 57d9a62 commit 5251f1b

2 files changed

Lines changed: 301 additions & 0 deletions

File tree

roaring64/benchmark123_test.go

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
//go:build go1.23
2+
// +build go1.23
3+
4+
package roaring64
5+
6+
import (
7+
"math/rand"
8+
"testing"
9+
)
10+
11+
func BenchmarkIterator123(b *testing.B) {
12+
bm := New()
13+
domain := uint64(100000000)
14+
count := 10000
15+
for j := 0; j < count; j++ {
16+
v := uint64(rand.Int63n(int64(domain)))
17+
bm.Add(v)
18+
}
19+
i := IntIterator64{}
20+
expectedCardinality := bm.GetCardinality()
21+
counter := uint64(0)
22+
23+
b.Run("simple iteration with alloc", func(b *testing.B) {
24+
for n := 0; n < b.N; n++ {
25+
counter = 0
26+
i := bm.Iterator()
27+
for i.HasNext() {
28+
i.Next()
29+
counter++
30+
}
31+
}
32+
b.StopTimer()
33+
})
34+
if counter != expectedCardinality {
35+
b.Fatalf("Cardinalities don't match: %d, %d", counter, expectedCardinality)
36+
}
37+
b.Run("simple iteration", func(b *testing.B) {
38+
for n := 0; n < b.N; n++ {
39+
counter = 0
40+
i.Initialize(bm)
41+
for i.HasNext() {
42+
i.Next()
43+
counter++
44+
}
45+
}
46+
b.StopTimer()
47+
})
48+
if counter != expectedCardinality {
49+
b.Fatalf("Cardinalities don't match: %d, %d", counter, expectedCardinality)
50+
}
51+
b.Run("values iteration", func(b *testing.B) {
52+
for n := 0; n < b.N; n++ {
53+
counter = 0
54+
Values(bm)(func(_ uint64) bool {
55+
counter++
56+
return true
57+
})
58+
}
59+
b.StopTimer()
60+
})
61+
if counter != expectedCardinality {
62+
b.Fatalf("Cardinalities don't match: %d, %d", counter, expectedCardinality)
63+
}
64+
b.Run("reverse iteration with alloc", func(b *testing.B) {
65+
for n := 0; n < b.N; n++ {
66+
counter = 0
67+
ir := bm.ReverseIterator()
68+
for ir.HasNext() {
69+
ir.Next()
70+
counter++
71+
}
72+
}
73+
b.StopTimer()
74+
})
75+
if counter != expectedCardinality {
76+
b.Fatalf("Cardinalities don't match: %d, %d", counter, expectedCardinality)
77+
}
78+
ir := IntReverseIterator64{}
79+
80+
b.Run("reverse iteration", func(b *testing.B) {
81+
for n := 0; n < b.N; n++ {
82+
counter = 0
83+
ir.Initialize(bm)
84+
for ir.HasNext() {
85+
ir.Next()
86+
counter++
87+
}
88+
}
89+
b.StopTimer()
90+
})
91+
if counter != expectedCardinality {
92+
b.Fatalf("Cardinalities don't match: %d, %d", counter, expectedCardinality)
93+
}
94+
b.Run("backward iteration", func(b *testing.B) {
95+
for n := 0; n < b.N; n++ {
96+
counter = 0
97+
Backward(bm)(func(_ uint64) bool {
98+
counter++
99+
return true
100+
})
101+
}
102+
b.StopTimer()
103+
})
104+
if counter != expectedCardinality {
105+
b.Fatalf("Cardinalities don't match: %d, %d", counter, expectedCardinality)
106+
}
107+
108+
b.Run("many iteration with alloc", func(b *testing.B) {
109+
for n := 0; n < b.N; n++ {
110+
counter = 0
111+
buf := make([]uint64, 1024)
112+
im := bm.ManyIterator()
113+
for n := im.NextMany(buf); n != 0; n = im.NextMany(buf) {
114+
counter += uint64(n)
115+
}
116+
}
117+
b.StopTimer()
118+
})
119+
if counter != expectedCardinality {
120+
b.Fatalf("Cardinalities don't match: %d, %d", counter, expectedCardinality)
121+
}
122+
im := ManyIntIterator64{}
123+
buf := make([]uint64, 1024)
124+
125+
b.Run("many iteration", func(b *testing.B) {
126+
for n := 0; n < b.N; n++ {
127+
counter = 0
128+
im.Initialize(bm)
129+
for n := im.NextMany(buf); n != 0; n = im.NextMany(buf) {
130+
counter += uint64(n)
131+
}
132+
}
133+
b.StopTimer()
134+
})
135+
if counter != expectedCardinality {
136+
b.Fatalf("Cardinalities don't match: %d, %d", counter, expectedCardinality)
137+
}
138+
139+
b.Run("values iteration 1.23", func(b *testing.B) {
140+
for n := 0; n < b.N; n++ {
141+
counter = 0
142+
for range Values(bm) {
143+
counter++
144+
}
145+
}
146+
b.StopTimer()
147+
})
148+
if counter != expectedCardinality {
149+
b.Fatalf("Cardinalities don't match: %d, %d", counter, expectedCardinality)
150+
}
151+
152+
b.Run("backward iteration 1.23", func(b *testing.B) {
153+
for n := 0; n < b.N; n++ {
154+
counter = 0
155+
for range Backward(bm) {
156+
counter++
157+
}
158+
}
159+
b.StopTimer()
160+
})
161+
if counter != expectedCardinality {
162+
b.Fatalf("Cardinalities don't match: %d, %d", counter, expectedCardinality)
163+
}
164+
}

roaring64/benchmark_test.go

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
package roaring64
2+
3+
import (
4+
"math/rand"
5+
"testing"
6+
)
7+
8+
// BENCHMARKS, to run them type "go test -bench Benchmark -run -"
9+
10+
// go test -bench BenchmarkIteratorAlloc -benchmem -run -
11+
func BenchmarkIteratorAlloc(b *testing.B) {
12+
bm := New()
13+
domain := uint64(100000000)
14+
count := 10000
15+
for j := 0; j < count; j++ {
16+
v := uint64(rand.Int63n(int64(domain)))
17+
bm.Add(v)
18+
}
19+
i := IntIterator64{}
20+
expectedCardinality := bm.GetCardinality()
21+
counter := uint64(0)
22+
b.Run("simple iteration with alloc", func(b *testing.B) {
23+
for n := 0; n < b.N; n++ {
24+
counter = 0
25+
i := bm.Iterator()
26+
for i.HasNext() {
27+
i.Next()
28+
counter++
29+
}
30+
}
31+
b.StopTimer()
32+
})
33+
if counter != expectedCardinality {
34+
b.Fatalf("Cardinalities don't match: %d, %d", counter, expectedCardinality)
35+
}
36+
b.Run("simple iteration", func(b *testing.B) {
37+
for n := 0; n < b.N; n++ {
38+
counter = 0
39+
i.Initialize(bm)
40+
for i.HasNext() {
41+
i.Next()
42+
counter++
43+
}
44+
}
45+
b.StopTimer()
46+
})
47+
if counter != expectedCardinality {
48+
b.Fatalf("Cardinalities don't match: %d, %d", counter, expectedCardinality)
49+
}
50+
b.Run("values iteration", func(b *testing.B) {
51+
for n := 0; n < b.N; n++ {
52+
counter = 0
53+
Values(bm)(func(_ uint64) bool {
54+
counter++
55+
return true
56+
})
57+
}
58+
b.StopTimer()
59+
})
60+
if counter != expectedCardinality {
61+
b.Fatalf("Cardinalities don't match: %d, %d", counter, expectedCardinality)
62+
}
63+
b.Run("reverse iteration with alloc", func(b *testing.B) {
64+
for n := 0; n < b.N; n++ {
65+
counter = 0
66+
ir := bm.ReverseIterator()
67+
for ir.HasNext() {
68+
ir.Next()
69+
counter++
70+
}
71+
}
72+
b.StopTimer()
73+
})
74+
if counter != expectedCardinality {
75+
b.Fatalf("Cardinalities don't match: %d, %d", counter, expectedCardinality)
76+
}
77+
ir := IntReverseIterator64{}
78+
79+
b.Run("reverse iteration", func(b *testing.B) {
80+
for n := 0; n < b.N; n++ {
81+
counter = 0
82+
ir.Initialize(bm)
83+
for ir.HasNext() {
84+
ir.Next()
85+
counter++
86+
}
87+
}
88+
b.StopTimer()
89+
})
90+
if counter != expectedCardinality {
91+
b.Fatalf("Cardinalities don't match: %d, %d", counter, expectedCardinality)
92+
}
93+
b.Run("backward iteration", func(b *testing.B) {
94+
for n := 0; n < b.N; n++ {
95+
counter = 0
96+
Backward(bm)(func(_ uint64) bool {
97+
counter++
98+
return true
99+
})
100+
}
101+
b.StopTimer()
102+
})
103+
if counter != expectedCardinality {
104+
b.Fatalf("Cardinalities don't match: %d, %d", counter, expectedCardinality)
105+
}
106+
107+
b.Run("many iteration with alloc", func(b *testing.B) {
108+
for n := 0; n < b.N; n++ {
109+
counter = 0
110+
buf := make([]uint64, 1024)
111+
im := bm.ManyIterator()
112+
for n := im.NextMany(buf); n != 0; n = im.NextMany(buf) {
113+
counter += uint64(n)
114+
}
115+
}
116+
b.StopTimer()
117+
})
118+
if counter != expectedCardinality {
119+
b.Fatalf("Cardinalities don't match: %d, %d", counter, expectedCardinality)
120+
}
121+
im := ManyIntIterator64{}
122+
buf := make([]uint64, 1024)
123+
124+
b.Run("many iteration", func(b *testing.B) {
125+
for n := 0; n < b.N; n++ {
126+
counter = 0
127+
im.Initialize(bm)
128+
for n := im.NextMany(buf); n != 0; n = im.NextMany(buf) {
129+
counter += uint64(n)
130+
}
131+
}
132+
b.StopTimer()
133+
})
134+
if counter != expectedCardinality {
135+
b.Fatalf("Cardinalities don't match: %d, %d", counter, expectedCardinality)
136+
}
137+
}

0 commit comments

Comments
 (0)