From 915d9de91dcbb2a3d8757e97f6e5f2c59a141b35 Mon Sep 17 00:00:00 2001 From: Cuong Manh Le Date: Tue, 1 Jun 2021 23:38:36 +0700 Subject: [PATCH] p2p/pex: reuse hash.Hasher per addrbook for speed (#6509) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- 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 4d76de6a5..38b0954e6 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -114,6 +114,7 @@ Friendly reminder: We have a [bug bounty program](https://hackerone.com/tendermi - [node/state] \#6370 graceful shutdown in the consensus reactor (@JayT106) - [crypto/merkle] \#6443 Improve HashAlternatives performance (@cuonglm) - [crypto/merkle] \#6513 Optimize HashAlternatives (@marbar3778) +- [p2p/pex] \#6509 Improve addrBook.hash performance (@cuonglm) ### BUG FIXES diff --git a/p2p/pex/addrbook.go b/p2p/pex/addrbook.go index 831848915..dd8922bce 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" mrand "math/rand" "net" @@ -101,15 +101,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. @@ -122,7 +125,6 @@ func NewAddrBook(filePath string, routabilityStrict bool) AddrBook { badPeers: make(map[p2p.NodeID]*knownAddress), filePath: filePath, routabilityStrict: routabilityStrict, - hashKey: newHashKey(), } am.init() am.BaseService = *service.NewBaseService(nil, "AddrBook", am) @@ -143,6 +145,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..7d2b636f1 --- /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.NodeID]struct{}), + addrLookup: make(map[p2p.NodeID]*knownAddress), + badPeers: make(map[p2p.NodeID]*knownAddress), + filePath: "", + routabilityStrict: true, + } + book.init() + msg := []byte(`foobar`) + b.ResetTimer() + for i := 0; i < b.N; i++ { + _, _ = book.hash(msg) + } +}