github.com/segmentio/parquet-go@v0.0.0-20230712180008-5d42db8f0d47/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  }