Skip to content

Commit 5c6ba6b

Browse files
cuiweixiefjl
andauthored
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 <[email protected]>
1 parent a7359ce commit 5c6ba6b

File tree

2 files changed

+29
-4
lines changed

2 files changed

+29
-4
lines changed

p2p/enode/node.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package enode
1919
import (
2020
"crypto/ecdsa"
2121
"encoding/base64"
22+
"encoding/binary"
2223
"encoding/hex"
2324
"errors"
2425
"fmt"
@@ -373,12 +374,14 @@ func DistCmp(target, a, b ID) int {
373374
// LogDist returns the logarithmic distance between a and b, log2(a ^ b).
374375
func LogDist(a, b ID) int {
375376
lz := 0
376-
for i := range a {
377-
x := a[i] ^ b[i]
377+
for i := 0; i < len(a); i += 8 {
378+
ai := binary.BigEndian.Uint64(a[i : i+8])
379+
bi := binary.BigEndian.Uint64(b[i : i+8])
380+
x := ai ^ bi
378381
if x == 0 {
379-
lz += 8
382+
lz += 64
380383
} else {
381-
lz += bits.LeadingZeros8(x)
384+
lz += bits.LeadingZeros64(x)
382385
break
383386
}
384387
}

p2p/enode/node_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,28 @@ func TestID_logdist(t *testing.T) {
378378
}
379379
}
380380

381+
func makeIDs() (ID, ID) {
382+
var a, b ID
383+
size := len(a)
384+
// last byte differs
385+
for i := 0; i < size-1; i++ {
386+
a[i] = 0xAA
387+
b[i] = 0xAA
388+
}
389+
a[size-1] = 0xAA
390+
b[size-1] = 0xAB
391+
return a, b
392+
}
393+
394+
// Benchmark LogDist
395+
func BenchmarkLogDist(b *testing.B) {
396+
aID, bID := makeIDs() // 256-bit ID
397+
b.ResetTimer()
398+
for i := 0; i < b.N; i++ {
399+
_ = LogDist(aID, bID)
400+
}
401+
}
402+
381403
// The random tests is likely to miss the case where a and b are equal,
382404
// this test checks it explicitly.
383405
func TestID_logdistEqual(t *testing.T) {

0 commit comments

Comments
 (0)