github.com/vc42/parquet-go@v0.0.0-20240320194221-1a9adb5f23f5/hashprobe/wyhash/wyhash_test.go (about) 1 package wyhash 2 3 import ( 4 "encoding/binary" 5 "math/rand" 6 "testing" 7 "time" 8 ) 9 10 func TestHash32(t *testing.T) { 11 if h := Hash32(42, 1); h != 0xda93b6f668a0496e { 12 t.Errorf("hash mismatch: %08x", h) 13 } 14 } 15 16 func TestMultiHash32(t *testing.T) { 17 const N = 10 18 hashes := [N]uintptr{} 19 values := [N]uint32{} 20 seed := uintptr(32) 21 22 for i := range values { 23 values[i] = uint32(i) 24 } 25 26 MultiHash32(hashes[:], values[:], seed) 27 28 for i := range values { 29 h := Hash32(values[i], seed) 30 31 if h != hashes[i] { 32 t.Errorf("hash(%d): want=%08x got=%08x", values[i], h, hashes[i]) 33 } 34 } 35 } 36 37 func BenchmarkHash32(b *testing.B) { 38 b.SetBytes(8) 39 value := rand.Uint32() 40 benchmarkHashThroughput(b, func(seed uintptr) int { 41 value = uint32(Hash32(value, seed)) 42 return 1 43 }) 44 } 45 46 func BenchmarkMultiHash32(b *testing.B) { 47 hashes := [512]uintptr{} 48 values := [512]uint32{} 49 b.SetBytes(4 * int64(len(hashes))) 50 benchmarkHashThroughput(b, func(seed uintptr) int { 51 MultiHash32(hashes[:], values[:], seed) 52 return len(hashes) 53 }) 54 } 55 56 func TestHash64(t *testing.T) { 57 if h := Hash64(42, 1); h != 0x6e69a6ede6b5a25e { 58 t.Errorf("hash mismatch: %016x", h) 59 } 60 } 61 62 func TestMultiHash64(t *testing.T) { 63 const N = 10 64 hashes := [N]uintptr{} 65 values := [N]uint64{} 66 seed := uintptr(64) 67 68 for i := range values { 69 values[i] = uint64(i) 70 } 71 72 MultiHash64(hashes[:], values[:], seed) 73 74 for i := range values { 75 h := Hash64(values[i], seed) 76 77 if h != hashes[i] { 78 t.Errorf("hash(%d): want=%016x got=%016x", values[i], h, hashes[i]) 79 } 80 } 81 } 82 83 func BenchmarkHash64(b *testing.B) { 84 b.SetBytes(8) 85 value := rand.Uint64() 86 benchmarkHashThroughput(b, func(seed uintptr) int { 87 value = uint64(Hash64(value, seed)) 88 return 1 89 }) 90 } 91 92 func BenchmarkMultiHash64(b *testing.B) { 93 hashes := [512]uintptr{} 94 values := [512]uint64{} 95 b.SetBytes(8 * int64(len(hashes))) 96 benchmarkHashThroughput(b, func(seed uintptr) int { 97 MultiHash64(hashes[:], values[:], seed) 98 return len(hashes) 99 }) 100 } 101 102 func TestHash128(t *testing.T) { 103 if h := Hash128([16]byte{0: 42}, 1); h != 0xcd09fcdae9a79e7c { 104 t.Errorf("hash mismatch: %016x", h) 105 } 106 } 107 108 func TestMultiHash128(t *testing.T) { 109 const N = 10 110 hashes := [N]uintptr{} 111 values := [N][16]byte{} 112 seed := uintptr(64) 113 114 for i := range values { 115 binary.LittleEndian.PutUint64(values[i][:8], uint64(i)) 116 } 117 118 MultiHash128(hashes[:], values[:], seed) 119 120 for i := range values { 121 h := Hash128(values[i], seed) 122 123 if h != hashes[i] { 124 t.Errorf("hash(%d): want=%016x got=%016x", values[i], h, hashes[i]) 125 } 126 } 127 } 128 129 func BenchmarkHash128(b *testing.B) { 130 b.SetBytes(8) 131 hash := uintptr(0) 132 value := [16]byte{} 133 binary.LittleEndian.PutUint64(value[:8], rand.Uint64()) 134 binary.LittleEndian.PutUint64(value[8:], rand.Uint64()) 135 benchmarkHashThroughput(b, func(seed uintptr) int { 136 hash = Hash128(value, seed) 137 return 1 138 }) 139 _ = hash 140 } 141 142 func BenchmarkMultiHash128(b *testing.B) { 143 hashes := [512]uintptr{} 144 values := [512][16]byte{} 145 b.SetBytes(16 * int64(len(hashes))) 146 benchmarkHashThroughput(b, func(seed uintptr) int { 147 MultiHash128(hashes[:], values[:], seed) 148 return len(hashes) 149 }) 150 } 151 152 func benchmarkHashThroughput(b *testing.B, f func(seed uintptr) int) { 153 hashes := int64(0) 154 start := time.Now() 155 156 for i := 0; i < b.N; i++ { 157 hashes += int64(f(uintptr(i))) 158 } 159 160 seconds := time.Since(start).Seconds() 161 b.ReportMetric(float64(hashes)/seconds, "hash/s") 162 }