From 080dfab992ecfbce39cc1ffa7ac59c0c021bf099 Mon Sep 17 00:00:00 2001 From: JayT106 Date: Wed, 21 Sep 2022 04:34:14 -0400 Subject: [PATCH] p2p/pex: reuse hash.Hasher per addrbook for speed (#6509) (#9445) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cherry-picking PR #6509 By pre-creating the hasher, instead of creating new one everytime addrbook.hash is called. ``` name old time/op new time/op delta AddrBook_hash-8 181ns ±13% 80ns ± 1% -56.08% (p=0.000 n=10+10) name old alloc/op new alloc/op delta AddrBook_hash-8 216B ± 0% 8B ± 0% -96.30% (p=0.000 n=10+10) name old allocs/op new allocs/op delta AddrBook_hash-8 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=10+10) ``` Fixed #6508 --- #### PR checklist - [x] Tests written/updated, or no tests needed - [x] `CHANGELOG_PENDING.md` updated, or no changelog entry needed - [x] Updated relevant documentation (`docs/`) and code comments, or no documentation updates needed --- CHANGELOG_PENDING.md | 1 + p2p/pex/addrbook.go | 26 +++++++++++++------------- p2p/pex/bench_test.go | 24 ++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 13 deletions(-) create mode 100644 p2p/pex/bench_test.go diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index db71c18d0..220028f41 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -22,6 +22,7 @@ ### IMPROVEMENTS - [pubsub] \#7319 Performance improvements for the event query API (@creachadair) +- [p2p/pex] \#6509 Improve addrBook.hash performance (@cuonglm) - [crypto/merkle] \#6443 & \#6513 Improve HashAlternatives performance (@cuonglm, @marbar3778) ### BUG FIXES diff --git a/p2p/pex/addrbook.go b/p2p/pex/addrbook.go index 95936a43c..2b8071041 100644 --- a/p2p/pex/addrbook.go +++ b/p2p/pex/addrbook.go @@ -5,9 +5,9 @@ package pex import ( - crand "crypto/rand" "encoding/binary" "fmt" + "hash" "math" "math/rand" "net" @@ -104,15 +104,18 @@ type addrBook struct { filePath string key string // random prefix for bucket placement routabilityStrict bool - hashKey []byte + hasher hash.Hash64 wg sync.WaitGroup } -func newHashKey() []byte { - result := make([]byte, highwayhash.Size) - crand.Read(result) //nolint:errcheck // ignore error - return result +func mustNewHasher() hash.Hash64 { + key := crypto.CRandBytes(highwayhash.Size) + hasher, err := highwayhash.New64(key) + if err != nil { + panic(err) + } + return hasher } // NewAddrBook creates a new address book. @@ -126,7 +129,6 @@ func NewAddrBook(filePath string, routabilityStrict bool) AddrBook { badPeers: make(map[p2p.ID]*knownAddress), filePath: filePath, routabilityStrict: routabilityStrict, - hashKey: newHashKey(), } am.init() am.BaseService = *service.NewBaseService(nil, "AddrBook", am) @@ -147,6 +149,7 @@ func (a *addrBook) init() { for i := range a.bucketsOld { a.bucketsOld[i] = make(map[string]*knownAddress) } + a.hasher = mustNewHasher() } // OnStart implements Service. @@ -938,10 +941,7 @@ func groupKeyFor(na *p2p.NetAddress, routabilityStrict bool) string { } func (a *addrBook) hash(b []byte) ([]byte, error) { - hasher, err := highwayhash.New64(a.hashKey) - if err != nil { - return nil, err - } - hasher.Write(b) - return hasher.Sum(nil), nil + a.hasher.Reset() + a.hasher.Write(b) + return a.hasher.Sum(nil), nil } diff --git a/p2p/pex/bench_test.go b/p2p/pex/bench_test.go new file mode 100644 index 000000000..13c37f7b1 --- /dev/null +++ b/p2p/pex/bench_test.go @@ -0,0 +1,24 @@ +package pex + +import ( + "testing" + + "github.com/tendermint/tendermint/p2p" +) + +func BenchmarkAddrBook_hash(b *testing.B) { + book := &addrBook{ + ourAddrs: make(map[string]struct{}), + privateIDs: make(map[p2p.ID]struct{}), + addrLookup: make(map[p2p.ID]*knownAddress), + badPeers: make(map[p2p.ID]*knownAddress), + filePath: "", + routabilityStrict: true, + } + book.init() + msg := []byte(`foobar`) + b.ResetTimer() + for i := 0; i < b.N; i++ { + _, _ = book.hash(msg) + } +}