From 6aa391fc4c0d1b9f42c7cd2ffc9c8037dc39e601 Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Wed, 3 May 2023 15:04:20 -0600 Subject: [PATCH] perf: limit use of unsafe UnsafeBytesToStr Unsafe []byte to string conversion is not required for map lookups, because the Go compiler does the conversion in a garbage-free way. Limit the scope of the unsafe strings in the few places it is needed (map deletion). WriteDOTGraph doesn't seem performance sensitive, so tolerate the extra garbage there. --- cache/cache.go | 11 +++++------ cmd/iaviewer/main.go | 5 ++--- mutable_tree.go | 7 +++---- tree_dotgraph.go | 5 ++--- 4 files changed, 12 insertions(+), 16 deletions(-) diff --git a/cache/cache.go b/cache/cache.go index 650480ef3..8b8097111 100644 --- a/cache/cache.go +++ b/cache/cache.go @@ -61,8 +61,7 @@ func New(maxElementCount int) Cache { } func (c *lruCache) Add(node Node) Node { - keyStr := ibytes.UnsafeBytesToStr(node.GetKey()) - if e, exists := c.dict[keyStr]; exists { + if e, exists := c.dict[string(node.GetKey())]; exists { c.ll.MoveToFront(e) old := e.Value e.Value = node @@ -70,7 +69,7 @@ func (c *lruCache) Add(node Node) Node { } elem := c.ll.PushFront(node) - c.dict[keyStr] = elem + c.dict[string(node.GetKey())] = elem if c.ll.Len() > c.maxElementCount { oldest := c.ll.Back() @@ -80,7 +79,7 @@ func (c *lruCache) Add(node Node) Node { } func (c *lruCache) Get(key []byte) Node { - if ele, hit := c.dict[ibytes.UnsafeBytesToStr(key)]; hit { + if ele, hit := c.dict[string(key)]; hit { c.ll.MoveToFront(ele) return ele.Value.(Node) } @@ -88,7 +87,7 @@ func (c *lruCache) Get(key []byte) Node { } func (c *lruCache) Has(key []byte) bool { - _, exists := c.dict[ibytes.UnsafeBytesToStr(key)] + _, exists := c.dict[string(key)] return exists } @@ -97,7 +96,7 @@ func (c *lruCache) Len() int { } func (c *lruCache) Remove(key []byte) Node { - if elem, exists := c.dict[ibytes.UnsafeBytesToStr(key)]; exists { + if elem, exists := c.dict[string(key)]; exists { return c.remove(elem) } return nil diff --git a/cmd/iaviewer/main.go b/cmd/iaviewer/main.go index 8fec9d4ca..d1fcbd9e3 100644 --- a/cmd/iaviewer/main.go +++ b/cmd/iaviewer/main.go @@ -14,7 +14,6 @@ import ( dbm "github.com/cosmos/cosmos-db" "github.com/cosmos/iavl" - ibytes "github.com/cosmos/iavl/internal/bytes" ) // TODO: make this configurable? @@ -102,8 +101,8 @@ func PrintDBStats(db dbm.DB) { defer itr.Close() for ; itr.Valid(); itr.Next() { - key := ibytes.UnsafeBytesToStr(itr.Key()[:1]) - prefix[key]++ + key := itr.Key()[:1] + prefix[string(key)]++ count++ } if err := itr.Error(); err != nil { diff --git a/mutable_tree.go b/mutable_tree.go index 3c8132a25..23b32605c 100644 --- a/mutable_tree.go +++ b/mutable_tree.go @@ -138,7 +138,7 @@ func (tree *MutableTree) Get(key []byte) ([]byte, error) { } if !tree.skipFastStorageUpgrade { - if fastNode, ok := tree.unsavedFastNodeAdditions[ibytes.UnsafeBytesToStr(key)]; ok { + if fastNode, ok := tree.unsavedFastNodeAdditions[string(key)]; ok { return fastNode.GetValue(), nil } // check if node was deleted @@ -770,9 +770,8 @@ func (tree *MutableTree) getUnsavedFastNodeRemovals() map[string]interface{} { } func (tree *MutableTree) addUnsavedAddition(key []byte, node *fastnode.Node) { - skey := ibytes.UnsafeBytesToStr(key) - delete(tree.unsavedFastNodeRemovals, skey) - tree.unsavedFastNodeAdditions[skey] = node + delete(tree.unsavedFastNodeRemovals, ibytes.UnsafeBytesToStr(key)) + tree.unsavedFastNodeAdditions[string(key)] = node } func (tree *MutableTree) saveFastNodeAdditions(batchCommmit bool) error { diff --git a/tree_dotgraph.go b/tree_dotgraph.go index 091f283e8..6c9edb883 100644 --- a/tree_dotgraph.go +++ b/tree_dotgraph.go @@ -8,7 +8,6 @@ import ( "os" "text/template" - ibytes "github.com/cosmos/iavl/internal/bytes" "github.com/emicklei/dot" ) @@ -61,12 +60,12 @@ func WriteDOTGraph(w io.Writer, tree *ImmutableTree, paths []PathToLeaf) { } shortHash := graphNode.Hash[:7] - graphNode.Label = mkLabel(ibytes.UnsafeBytesToStr(node.key), 16, "sans-serif") + graphNode.Label = mkLabel(string(node.key), 16, "sans-serif") graphNode.Label += mkLabel(shortHash, 10, "monospace") graphNode.Label += mkLabel(fmt.Sprintf("nodeKey=%v", node.nodeKey), 10, "monospace") if node.value != nil { - graphNode.Label += mkLabel(ibytes.UnsafeBytesToStr(node.value), 10, "sans-serif") + graphNode.Label += mkLabel(string(node.value), 10, "sans-serif") } if node.subtreeHeight == 0 {