...
1 package z
2
3 import (
4 "hash/fnv"
5 "math/rand"
6 "sync/atomic"
7 "testing"
8 "time"
9
10 "github.com/dgryski/go-farm"
11 )
12
13 func BenchmarkMemHash(b *testing.B) {
14 buf := make([]byte, 64)
15 rand.Read(buf)
16
17 b.ReportAllocs()
18 b.ResetTimer()
19 for i := 0; i < b.N; i++ {
20 _ = MemHash(buf)
21 }
22 b.SetBytes(int64(len(buf)))
23 }
24
25 func BenchmarkMemHashString(b *testing.B) {
26 s := "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
27
28 b.ReportAllocs()
29 b.ResetTimer()
30 for i := 0; i < b.N; i++ {
31 _ = MemHashString(s)
32 }
33 b.SetBytes(int64(len(s)))
34 }
35
36 func BenchmarkSip(b *testing.B) {
37 buf := make([]byte, 64)
38 rand.Read(buf)
39 for i := 0; i < b.N; i++ {
40 SipHash(buf)
41 }
42 }
43
44 func BenchmarkFarm(b *testing.B) {
45 buf := make([]byte, 64)
46 rand.Read(buf)
47 for i := 0; i < b.N; i++ {
48 farm.Fingerprint64(buf)
49 }
50 }
51
52 func BenchmarkFnv(b *testing.B) {
53 buf := make([]byte, 64)
54 rand.Read(buf)
55 f := fnv.New64a()
56 for i := 0; i < b.N; i++ {
57 f.Write(buf)
58 f.Sum64()
59 f.Reset()
60 }
61 }
62
63 func SipHash(p []byte) (l, h uint64) {
64
65 v0 := uint64(8317987320269560794)
66 v1 := uint64(7237128889637516672)
67 v2 := uint64(7816392314733513934)
68 v3 := uint64(8387220255325274014)
69 t := uint64(len(p)) << 56
70
71
72 for len(p) >= 8 {
73 m := uint64(p[0]) | uint64(p[1])<<8 | uint64(p[2])<<16 | uint64(p[3])<<24 |
74 uint64(p[4])<<32 | uint64(p[5])<<40 | uint64(p[6])<<48 | uint64(p[7])<<56
75
76 v3 ^= m
77
78
79 v0 += v1
80 v1 = v1<<13 | v1>>51
81 v1 ^= v0
82 v0 = v0<<32 | v0>>32
83
84 v2 += v3
85 v3 = v3<<16 | v3>>48
86 v3 ^= v2
87
88 v0 += v3
89 v3 = v3<<21 | v3>>43
90 v3 ^= v0
91
92 v2 += v1
93 v1 = v1<<17 | v1>>47
94 v1 ^= v2
95 v2 = v2<<32 | v2>>32
96
97
98 v0 += v1
99 v1 = v1<<13 | v1>>51
100 v1 ^= v0
101 v0 = v0<<32 | v0>>32
102
103 v2 += v3
104 v3 = v3<<16 | v3>>48
105 v3 ^= v2
106
107 v0 += v3
108 v3 = v3<<21 | v3>>43
109 v3 ^= v0
110
111 v2 += v1
112 v1 = v1<<17 | v1>>47
113 v1 ^= v2
114 v2 = v2<<32 | v2>>32
115
116 v0 ^= m
117 p = p[8:]
118 }
119
120
121 switch len(p) {
122 case 7:
123 t |= uint64(p[6]) << 48
124 fallthrough
125 case 6:
126 t |= uint64(p[5]) << 40
127 fallthrough
128 case 5:
129 t |= uint64(p[4]) << 32
130 fallthrough
131 case 4:
132 t |= uint64(p[3]) << 24
133 fallthrough
134 case 3:
135 t |= uint64(p[2]) << 16
136 fallthrough
137 case 2:
138 t |= uint64(p[1]) << 8
139 fallthrough
140 case 1:
141 t |= uint64(p[0])
142 }
143
144 v3 ^= t
145
146
147 v0 += v1
148 v1 = v1<<13 | v1>>51
149 v1 ^= v0
150 v0 = v0<<32 | v0>>32
151
152 v2 += v3
153 v3 = v3<<16 | v3>>48
154 v3 ^= v2
155
156 v0 += v3
157 v3 = v3<<21 | v3>>43
158 v3 ^= v0
159
160 v2 += v1
161 v1 = v1<<17 | v1>>47
162 v1 ^= v2
163 v2 = v2<<32 | v2>>32
164
165
166 v0 += v1
167 v1 = v1<<13 | v1>>51
168 v1 ^= v0
169 v0 = v0<<32 | v0>>32
170
171 v2 += v3
172 v3 = v3<<16 | v3>>48
173 v3 ^= v2
174
175 v0 += v3
176 v3 = v3<<21 | v3>>43
177 v3 ^= v0
178
179 v2 += v1
180 v1 = v1<<17 | v1>>47
181 v1 ^= v2
182 v2 = v2<<32 | v2>>32
183
184 v0 ^= t
185
186
187 v2 ^= 0xff
188
189
190 v0 += v1
191 v1 = v1<<13 | v1>>51
192 v1 ^= v0
193 v0 = v0<<32 | v0>>32
194
195 v2 += v3
196 v3 = v3<<16 | v3>>48
197 v3 ^= v2
198
199 v0 += v3
200 v3 = v3<<21 | v3>>43
201 v3 ^= v0
202
203 v2 += v1
204 v1 = v1<<17 | v1>>47
205 v1 ^= v2
206 v2 = v2<<32 | v2>>32
207
208
209 v0 += v1
210 v1 = v1<<13 | v1>>51
211 v1 ^= v0
212 v0 = v0<<32 | v0>>32
213
214 v2 += v3
215 v3 = v3<<16 | v3>>48
216 v3 ^= v2
217
218 v0 += v3
219 v3 = v3<<21 | v3>>43
220 v3 ^= v0
221
222 v2 += v1
223 v1 = v1<<17 | v1>>47
224 v1 ^= v2
225 v2 = v2<<32 | v2>>32
226
227
228 v0 += v1
229 v1 = v1<<13 | v1>>51
230 v1 ^= v0
231 v0 = v0<<32 | v0>>32
232
233 v2 += v3
234 v3 = v3<<16 | v3>>48
235 v3 ^= v2
236
237 v0 += v3
238 v3 = v3<<21 | v3>>43
239 v3 ^= v0
240
241 v2 += v1
242 v1 = v1<<17 | v1>>47
243 v1 ^= v2
244 v2 = v2<<32 | v2>>32
245
246
247 v0 += v1
248 v1 = v1<<13 | v1>>51
249 v1 ^= v0
250 v0 = v0<<32 | v0>>32
251
252 v2 += v3
253 v3 = v3<<16 | v3>>48
254 v3 ^= v2
255
256 v0 += v3
257 v3 = v3<<21 | v3>>43
258 v3 ^= v0
259
260 v2 += v1
261 v1 = v1<<17 | v1>>47
262 v1 ^= v2
263 v2 = v2<<32 | v2>>32
264
265
266
267 hash := v0 ^ v1 ^ v2 ^ v3
268 h = hash >> 1
269 l = hash << 1 >> 1
270 return l, h
271 }
272
273 func BenchmarkNanoTime(b *testing.B) {
274 for i := 0; i < b.N; i++ {
275 NanoTime()
276 }
277 }
278
279 func BenchmarkCPUTicks(b *testing.B) {
280 for i := 0; i < b.N; i++ {
281 CPUTicks()
282 }
283 }
284
285
286
287
288
289
290
291
292
293
294 func benchmarkRand(b *testing.B, fab func() func() uint32) {
295 b.RunParallel(func(pb *testing.PB) {
296 gen := fab()
297 for pb.Next() {
298 gen()
299 }
300 })
301 }
302
303 func BenchmarkFastRand(b *testing.B) {
304 benchmarkRand(b, func() func() uint32 {
305 return FastRand
306 })
307 }
308
309 func BenchmarkRandSource(b *testing.B) {
310 benchmarkRand(b, func() func() uint32 {
311 s := rand.New(rand.NewSource(time.Now().Unix()))
312 return func() uint32 { return s.Uint32() }
313 })
314 }
315
316 func BenchmarkRandGlobal(b *testing.B) {
317 benchmarkRand(b, func() func() uint32 {
318 return func() uint32 { return rand.Uint32() }
319 })
320 }
321
322 func BenchmarkRandAtomic(b *testing.B) {
323 var x uint32
324 benchmarkRand(b, func() func() uint32 {
325 return func() uint32 { return uint32(atomic.AddUint32(&x, 1)) }
326 })
327 }
328
View as plain text