util/deephash: optimize hashing of byte arrays, reduce allocs in Hash
name old time/op new time/op delta Hash-6 173µs ± 4% 101µs ± 3% -41.69% (p=0.000 n=10+9) HashMapAcyclic-6 101µs ± 5% 105µs ± 3% +3.52% (p=0.001 n=9+10) TailcfgNode-6 29.4µs ± 2% 16.4µs ± 3% -44.25% (p=0.000 n=8+10) name old alloc/op new alloc/op delta Hash-6 3.60kB ± 0% 1.13kB ± 0% -68.70% (p=0.000 n=10+10) HashMapAcyclic-6 2.53kB ± 0% 2.53kB ± 0% ~ (p=0.137 n=10+8) TailcfgNode-6 528B ± 0% 0B -100.00% (p=0.000 n=10+10) name old allocs/op new allocs/op delta Hash-6 84.0 ± 0% 40.0 ± 0% -52.38% (p=0.000 n=10+10) HashMapAcyclic-6 202 ± 0% 202 ± 0% ~ (all equal) TailcfgNode-6 11.0 ± 0% 0.0 -100.00% (p=0.000 n=10+10) Updates tailscale/corp#2130 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:

committed by
Brad Fitzpatrick

parent
3962744450
commit
6dc38ff25c
@ -169,6 +169,29 @@ func TestHashMapAcyclic(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrintArray(t *testing.T) {
|
||||
type T struct {
|
||||
X [32]byte
|
||||
}
|
||||
x := &T{X: [32]byte{1: 1, 31: 31}}
|
||||
var got bytes.Buffer
|
||||
bw := bufio.NewWriter(&got)
|
||||
h := &hasher{
|
||||
bw: bw,
|
||||
visited: map[uintptr]bool{},
|
||||
}
|
||||
h.print(reflect.ValueOf(x))
|
||||
bw.Flush()
|
||||
const want = "struct" +
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x01" + // 1 field
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00" + // 0th field
|
||||
// the 32 bytes:
|
||||
"\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f"
|
||||
if got := got.Bytes(); string(got) != want {
|
||||
t.Errorf("wrong:\n got: %q\nwant: %q\n", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkHashMapAcyclic(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
m := map[int]string{}
|
||||
@ -238,3 +261,28 @@ func TestMapCyclicFallback(t *testing.T) {
|
||||
v.M["m"] = v.M
|
||||
Hash(v)
|
||||
}
|
||||
|
||||
func TestArrayAllocs(t *testing.T) {
|
||||
type T struct {
|
||||
X [32]byte
|
||||
}
|
||||
x := &T{X: [32]byte{1: 1, 2: 2, 3: 3, 4: 4}}
|
||||
n := int(testing.AllocsPerRun(1000, func() {
|
||||
sink = Hash(x)
|
||||
}))
|
||||
if n > 0 {
|
||||
t.Errorf("allocs = %v; want 0", n)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkHashArray(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
type T struct {
|
||||
X [32]byte
|
||||
}
|
||||
x := &T{X: [32]byte{1: 1, 2: 2, 3: 3, 4: 4}}
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
sink = Hash(x)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user