1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package btree
16
17 import (
18 "fmt"
19 "sort"
20 "testing"
21 )
22
23 const benchmarkTreeSize = 10000
24
25 var degrees = []int{2, 8, 32, 64}
26
27 func BenchmarkInsert(b *testing.B) {
28 insertP := perm(benchmarkTreeSize)
29 for _, d := range degrees {
30 b.Run(fmt.Sprintf("degree=%d", d), func(b *testing.B) {
31 i := 0
32 for i < b.N {
33 tr := New(d, less)
34 for _, m := range insertP {
35 tr.Set(m.Key, m.Value)
36 i++
37 if i >= b.N {
38 return
39 }
40 }
41 }
42 })
43 }
44 }
45
46 func BenchmarkDeleteInsert(b *testing.B) {
47 insertP := perm(benchmarkTreeSize)
48 for _, d := range degrees {
49 b.Run(fmt.Sprintf("degree=%d", d), func(b *testing.B) {
50 tr := New(d, less)
51 for _, m := range insertP {
52 tr.Set(m.Key, m.Value)
53 }
54 b.ResetTimer()
55 for i := 0; i < b.N; i++ {
56 m := insertP[i%benchmarkTreeSize]
57 tr.Delete(m.Key)
58 tr.Set(m.Key, m.Value)
59 }
60 })
61 }
62 }
63
64 func BenchmarkDeleteInsertCloneOnce(b *testing.B) {
65 insertP := perm(benchmarkTreeSize)
66 for _, d := range degrees {
67 b.Run(fmt.Sprintf("degree=%d", d), func(b *testing.B) {
68 tr := New(d, less)
69 for _, m := range insertP {
70 tr.Set(m.Key, m.Value)
71 }
72 tr = tr.Clone()
73 b.ResetTimer()
74 for i := 0; i < b.N; i++ {
75 m := insertP[i%benchmarkTreeSize]
76 tr.Delete(m.Key)
77 tr.Set(m.Key, m.Value)
78 }
79 })
80 }
81 }
82
83 func BenchmarkDeleteInsertCloneEachTime(b *testing.B) {
84 insertP := perm(benchmarkTreeSize)
85 for _, d := range degrees {
86 b.Run(fmt.Sprintf("degree=%d", d), func(b *testing.B) {
87 tr := New(d, less)
88 for _, m := range insertP {
89 tr.Set(m.Key, m.Value)
90 }
91 b.ResetTimer()
92 for i := 0; i < b.N; i++ {
93 tr = tr.Clone()
94 m := insertP[i%benchmarkTreeSize]
95 tr.Delete(m.Key)
96 tr.Set(m.Key, m.Value)
97 }
98 })
99 }
100 }
101
102 func BenchmarkDelete(b *testing.B) {
103 insertP := perm(benchmarkTreeSize)
104 removeP := perm(benchmarkTreeSize)
105 for _, d := range degrees {
106 b.Run(fmt.Sprintf("degree=%d", d), func(b *testing.B) {
107 i := 0
108 for i < b.N {
109 b.StopTimer()
110 tr := New(d, less)
111 for _, v := range insertP {
112 tr.Set(v.Key, v.Value)
113 }
114 b.StartTimer()
115 for _, m := range removeP {
116 tr.Delete(m.Key)
117 i++
118 if i >= b.N {
119 return
120 }
121 }
122 if tr.Len() > 0 {
123 panic(tr.Len())
124 }
125 }
126 })
127 }
128 }
129
130 func BenchmarkGet(b *testing.B) {
131 insertP := perm(benchmarkTreeSize)
132 getP := perm(benchmarkTreeSize)
133 for _, d := range degrees {
134 b.Run(fmt.Sprintf("degree=%d", d), func(b *testing.B) {
135 i := 0
136 for i < b.N {
137 b.StopTimer()
138 tr := New(d, less)
139 for _, v := range insertP {
140 tr.Set(v.Key, v.Value)
141 }
142 b.StartTimer()
143 for _, m := range getP {
144 tr.Get(m.Key)
145 i++
146 if i >= b.N {
147 return
148 }
149 }
150 }
151 })
152 }
153 }
154
155 func BenchmarkGetWithIndex(b *testing.B) {
156 insertP := perm(benchmarkTreeSize)
157 getP := perm(benchmarkTreeSize)
158 for _, d := range degrees {
159 b.Run(fmt.Sprintf("degree=%d", d), func(b *testing.B) {
160 i := 0
161 for i < b.N {
162 b.StopTimer()
163 tr := New(d, less)
164 for _, v := range insertP {
165 tr.Set(v.Key, v.Value)
166 }
167 b.StartTimer()
168 for _, m := range getP {
169 tr.GetWithIndex(m.Key)
170 i++
171 if i >= b.N {
172 return
173 }
174 }
175 }
176 })
177 }
178 }
179
180 func BenchmarkGetCloneEachTime(b *testing.B) {
181 insertP := perm(benchmarkTreeSize)
182 getP := perm(benchmarkTreeSize)
183 for _, d := range degrees {
184 b.Run(fmt.Sprintf("degree=%d", d), func(b *testing.B) {
185 i := 0
186 for i < b.N {
187 b.StopTimer()
188 tr := New(d, less)
189 for _, m := range insertP {
190 tr.Set(m.Key, m.Value)
191 }
192 b.StartTimer()
193 for _, m := range getP {
194 tr = tr.Clone()
195 tr.Get(m.Key)
196 i++
197 if i >= b.N {
198 return
199 }
200 }
201 }
202 })
203 }
204 }
205
206 func BenchmarkFind(b *testing.B) {
207 for _, d := range degrees {
208 var items []item
209 for i := 0; i < 2*d; i++ {
210 items = append(items, item{i, i})
211 }
212 b.Run(fmt.Sprintf("size=%d", len(items)), func(b *testing.B) {
213 for _, alg := range []struct {
214 name string
215 fun func(Key, []item) (int, bool)
216 }{
217 {"binary", findBinary},
218 {"linear", findLinear},
219 } {
220 b.Run(alg.name, func(b *testing.B) {
221 for i := 0; i < b.N; i++ {
222 for j := 0; j < len(items); j++ {
223 alg.fun(items[j].key, items)
224 }
225 }
226 })
227 }
228 })
229 }
230 }
231
232 func findBinary(k Key, s []item) (int, bool) {
233 i := sort.Search(len(s), func(i int) bool { return less(k, s[i].key) })
234
235 if i > 0 && !less(s[i-1].key, k) {
236 return i - 1, true
237 }
238 return i, false
239 }
240
241 func findLinear(k Key, s []item) (int, bool) {
242 var i int
243 for i = 0; i < len(s); i++ {
244 if less(k, s[i].key) {
245 break
246 }
247 }
248 if i > 0 && !less(s[i-1].key, k) {
249 return i - 1, true
250 }
251 return i, false
252 }
253
View as plain text