tailscale/internal/deephash/mapiter_future.go
Josh Bleecher Snyder 051d2f47e5 internal/deephash: re-use MapIter
name              old time/op    new time/op    delta
Hash-8              12.4µs ± 0%    12.4µs ± 0%    -0.33%  (p=0.002 n=10+9)
HashMapAcyclic-8    21.2µs ± 0%    21.3µs ± 0%    +0.45%  (p=0.000 n=8+8)

name              old alloc/op   new alloc/op   delta
Hash-8                793B ± 0%      408B ± 0%   -48.55%  (p=0.000 n=10+10)
HashMapAcyclic-8      128B ± 0%        0B       -100.00%  (p=0.000 n=10+10)

name              old allocs/op  new allocs/op  delta
Hash-8                9.00 ± 0%      6.00 ± 0%   -33.33%  (p=0.000 n=10+10)
HashMapAcyclic-8      1.00 ± 0%      0.00       -100.00%  (p=0.000 n=10+10)

Depends on https://github.com/golang/go/issues/46293.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-05-24 14:47:41 -07:00

43 lines
1.4 KiB
Go

// Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build tailscale_go
package deephash
import "reflect"
// iterKey returns the current iter key.
// scratch is a re-usable reflect.Value.
// iterKey may store the iter key in scratch and return scratch,
// or it may allocate and return a new reflect.Value.
func iterKey(iter *reflect.MapIter, scratch reflect.Value) reflect.Value {
iter.SetKey(scratch)
return scratch
}
// iterVal returns the current iter val.
// scratch is a re-usable reflect.Value.
// iterVal may store the iter val in scratch and return scratch,
// or it may allocate and return a new reflect.Value.
func iterVal(iter *reflect.MapIter, scratch reflect.Value) reflect.Value {
iter.SetValue(scratch)
return scratch
}
// mapIter returns a map iterator for mapVal.
// scratch is a re-usable reflect.MapIter.
// mapIter may re-use scratch and return it,
// or it may allocate and return a new *reflect.MapIter.
// If mapVal is the zero reflect.Value, mapIter may return nil.
func mapIter(scratch *reflect.MapIter, mapVal reflect.Value) *reflect.MapIter {
scratch.Reset(mapVal) // always Reset, to allow the caller to avoid pinning memory
if !mapVal.IsValid() {
// Returning scratch would also be OK.
// Do this for consistency with the non-optimized version.
return nil
}
return scratch
}