github.com/songzhibin97/go-baseutils@v0.0.2-0.20240302024150-487d8ce9c082/internal/wyhash/digest_test.go (about) 1 package wyhash 2 3 import ( 4 "fmt" 5 "runtime" 6 "testing" 7 8 _ "unsafe" // for linkname 9 ) 10 11 //go:linkname runtime_fastrand runtime.fastrand 12 func runtime_fastrand() uint32 13 14 //go:nosplit 15 func fastrandn(n uint32) uint32 { 16 // This is similar to Uint32() % n, but faster. 17 // See https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/ 18 return uint32(uint64(runtime_fastrand()) * uint64(n) >> 32) 19 } 20 21 func TestDigest(t *testing.T) { 22 d := NewDefault() 23 for size := 0; size <= 1024; size++ { 24 data := make([]byte, size) 25 for i := range data { 26 data[i] = byte(fastrandn(256)) 27 } 28 // Random write small data. 29 var r int 30 if size == 0 { 31 r = 0 32 } else { 33 r = int(fastrandn(uint32(len(data)))) 34 } 35 d.Write(data[:r]) 36 d.Write(data[r:]) 37 if d.Sum64() != Sum64(data) { 38 t.Fatal(size, d.Sum64(), Sum64(data)) 39 } 40 d.Reset() 41 } 42 43 largedata := make([]byte, 1024*1024) 44 for i := range largedata { 45 largedata[i] = byte(fastrandn(256)) 46 } 47 48 var a, b int 49 digest := NewDefault() 50 partsizelimit := 300 51 for { 52 if len(largedata)-a < 300 { 53 b = len(largedata) - a 54 } else { 55 b = int(fastrandn(uint32(partsizelimit))) 56 } 57 digest.Write(largedata[a : a+b]) 58 if Sum64(largedata[:a+b]) != digest.Sum64() { 59 t.Fatal(a, b) 60 } 61 a += b 62 if a == len(largedata) { 63 break 64 } 65 } 66 } 67 68 func BenchmarkDigest(b *testing.B) { 69 sizes := []int{33, 64, 96, 128, 129, 240, 241, 70 512, 1024, 10 * 1024, 71 } 72 73 for _, size := range sizes { 74 b.Run(fmt.Sprintf("%d", size), func(b *testing.B) { 75 b.SetBytes(int64(size)) 76 var acc uint64 77 data := make([]byte, size) 78 b.ReportAllocs() 79 b.ResetTimer() 80 81 for i := 0; i < b.N; i++ { 82 d := NewDefault() 83 d.Write(data) 84 acc = d.Sum64() 85 } 86 runtime.KeepAlive(acc) 87 }) 88 } 89 }