From 7329014486241083cffbf7933823803b76d22903 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Thu, 16 May 2019 14:57:07 +0100 Subject: [PATCH] Improve FlipRightBit by doing it directly. Seems roughly 6x faster, called for every level in the tree via Siblings() in the sparse merkle code. BenchmarkFlipRightBit-12 200000000 9.19 ns/op BenchmarkFlipRightBit-12 2000000000 1.62 ns/op --- storage/types.go | 6 +++--- storage/types_test.go | 9 ++++++++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/storage/types.go b/storage/types.go index 8d492038f6..d2cfae8f78 100644 --- a/storage/types.go +++ b/storage/types.go @@ -339,7 +339,8 @@ func (n *NodeID) Copy() *NodeID { // FlipRightBit flips the ith bit from LSB func (n *NodeID) FlipRightBit(i int) *NodeID { - n.SetBit(i, n.Bit(i)^1) + bIndex := (n.PathLenBits() - i - 1) / 8 + n.Path[bIndex] ^= 1 << uint(i%8) return n } @@ -370,8 +371,7 @@ func (n *NodeID) MaskLeft(depth int) *NodeID { // in the binary tree (often termed sibling node). func (n *NodeID) Neighbor() *NodeID { height := n.PathLenBits() - n.PrefixLenBits - n.FlipRightBit(height) - return n + return n.FlipRightBit(height) } // Siblings returns the siblings of the given node. diff --git a/storage/types_test.go b/storage/types_test.go index 534f9939b0..94f0923b8f 100644 --- a/storage/types_test.go +++ b/storage/types_test.go @@ -574,7 +574,7 @@ func TestSetBit(t *testing.T) { } } -func TestFlipBit(t *testing.T) { +func TestFlipRightBit(t *testing.T) { for _, tc := range []struct { index []byte i int @@ -869,3 +869,10 @@ func BenchmarkAsKey(b *testing.B) { _ = nID.AsKey() } } + +func BenchmarkFlipRightBit(b *testing.B) { + nID := NewNodeIDFromHash(h2b("000102030405060708090A0B0C0D0E0F10111213")) + for i := 0; i < b.N; i++ { + nID.FlipRightBit(27) + } +}