mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-02-26 07:37:20 +00:00
p2p/enode: optimize LogDist (#32887)
This speeds up LogDist by 75% using 64-bit operations instead of byte-wise XOR. --------- Co-authored-by: Felix Lange <fjl@twurst.com>
This commit is contained in:
parent
a7359ceb69
commit
5c6ba6b400
2 changed files with 29 additions and 4 deletions
|
|
@ -19,6 +19,7 @@ package enode
|
|||
import (
|
||||
"crypto/ecdsa"
|
||||
"encoding/base64"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
|
@ -373,12 +374,14 @@ func DistCmp(target, a, b ID) int {
|
|||
// LogDist returns the logarithmic distance between a and b, log2(a ^ b).
|
||||
func LogDist(a, b ID) int {
|
||||
lz := 0
|
||||
for i := range a {
|
||||
x := a[i] ^ b[i]
|
||||
for i := 0; i < len(a); i += 8 {
|
||||
ai := binary.BigEndian.Uint64(a[i : i+8])
|
||||
bi := binary.BigEndian.Uint64(b[i : i+8])
|
||||
x := ai ^ bi
|
||||
if x == 0 {
|
||||
lz += 8
|
||||
lz += 64
|
||||
} else {
|
||||
lz += bits.LeadingZeros8(x)
|
||||
lz += bits.LeadingZeros64(x)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -378,6 +378,28 @@ func TestID_logdist(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func makeIDs() (ID, ID) {
|
||||
var a, b ID
|
||||
size := len(a)
|
||||
// last byte differs
|
||||
for i := 0; i < size-1; i++ {
|
||||
a[i] = 0xAA
|
||||
b[i] = 0xAA
|
||||
}
|
||||
a[size-1] = 0xAA
|
||||
b[size-1] = 0xAB
|
||||
return a, b
|
||||
}
|
||||
|
||||
// Benchmark LogDist
|
||||
func BenchmarkLogDist(b *testing.B) {
|
||||
aID, bID := makeIDs() // 256-bit ID
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = LogDist(aID, bID)
|
||||
}
|
||||
}
|
||||
|
||||
// The random tests is likely to miss the case where a and b are equal,
|
||||
// this test checks it explicitly.
|
||||
func TestID_logdistEqual(t *testing.T) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue