p2p/pex: reuse hash.Hasher per addrbook for speed (#6509) (#9445)

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
This commit is contained in:
JayT106
2022-09-21 08:34:14 +00:00
committed by GitHub
parent ab4238a0e2
commit 080dfab992
3 changed files with 38 additions and 13 deletions
+1
View File
@@ -22,6 +22,7 @@
### IMPROVEMENTS ### IMPROVEMENTS
- [pubsub] \#7319 Performance improvements for the event query API (@creachadair) - [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) - [crypto/merkle] \#6443 & \#6513 Improve HashAlternatives performance (@cuonglm, @marbar3778)
### BUG FIXES ### BUG FIXES
+13 -13
View File
@@ -5,9 +5,9 @@
package pex package pex
import ( import (
crand "crypto/rand"
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"hash"
"math" "math"
"math/rand" "math/rand"
"net" "net"
@@ -104,15 +104,18 @@ type addrBook struct {
filePath string filePath string
key string // random prefix for bucket placement key string // random prefix for bucket placement
routabilityStrict bool routabilityStrict bool
hashKey []byte hasher hash.Hash64
wg sync.WaitGroup wg sync.WaitGroup
} }
func newHashKey() []byte { func mustNewHasher() hash.Hash64 {
result := make([]byte, highwayhash.Size) key := crypto.CRandBytes(highwayhash.Size)
crand.Read(result) //nolint:errcheck // ignore error hasher, err := highwayhash.New64(key)
return result if err != nil {
panic(err)
}
return hasher
} }
// NewAddrBook creates a new address book. // NewAddrBook creates a new address book.
@@ -126,7 +129,6 @@ func NewAddrBook(filePath string, routabilityStrict bool) AddrBook {
badPeers: make(map[p2p.ID]*knownAddress), badPeers: make(map[p2p.ID]*knownAddress),
filePath: filePath, filePath: filePath,
routabilityStrict: routabilityStrict, routabilityStrict: routabilityStrict,
hashKey: newHashKey(),
} }
am.init() am.init()
am.BaseService = *service.NewBaseService(nil, "AddrBook", am) am.BaseService = *service.NewBaseService(nil, "AddrBook", am)
@@ -147,6 +149,7 @@ func (a *addrBook) init() {
for i := range a.bucketsOld { for i := range a.bucketsOld {
a.bucketsOld[i] = make(map[string]*knownAddress) a.bucketsOld[i] = make(map[string]*knownAddress)
} }
a.hasher = mustNewHasher()
} }
// OnStart implements Service. // OnStart implements Service.
@@ -938,10 +941,7 @@ func groupKeyFor(na *p2p.NetAddress, routabilityStrict bool) string {
} }
func (a *addrBook) hash(b []byte) ([]byte, error) { func (a *addrBook) hash(b []byte) ([]byte, error) {
hasher, err := highwayhash.New64(a.hashKey) a.hasher.Reset()
if err != nil { a.hasher.Write(b)
return nil, err return a.hasher.Sum(nil), nil
}
hasher.Write(b)
return hasher.Sum(nil), nil
} }
+24
View File
@@ -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)
}
}