From f93b81898e76910899220fd9cae156b3feccb0ce Mon Sep 17 00:00:00 2001 From: maskpp Date: Wed, 23 Apr 2025 23:25:28 +0800 Subject: [PATCH] better performance the usage of maps --- core/rawdb/database.go | 6 ++++-- core/state/snapshot/difflayer.go | 8 +++++--- core/txpool/blobpool/evictheap.go | 5 +++-- core/txpool/legacypool/legacypool.go | 4 ++-- p2p/netutil/net.go | 6 ++++-- triedb/pathdb/history.go | 10 +++++++--- triedb/pathdb/states.go | 8 +++++--- 7 files changed, 30 insertions(+), 17 deletions(-) diff --git a/core/rawdb/database.go b/core/rawdb/database.go index 2a50e3f9ee..acc36ae649 100644 --- a/core/rawdb/database.go +++ b/core/rawdb/database.go @@ -20,7 +20,6 @@ import ( "bytes" "errors" "fmt" - "maps" "os" "path/filepath" "slices" @@ -33,6 +32,7 @@ import ( "github.com/ethereum/go-ethereum/ethdb/memorydb" "github.com/ethereum/go-ethereum/log" "github.com/olekukonko/tablewriter" + "golang.org/x/exp/maps" ) var ErrDeleteRangeInterrupted = errors.New("safe delete range operation interrupted") @@ -552,7 +552,9 @@ func InspectDatabase(db ethdb.Database, keyPrefix, keyStart []byte) error { if unaccounted.size > 0 { log.Error("Database contains unaccounted data", "size", unaccounted.size, "count", unaccounted.count) - for _, e := range slices.SortedFunc(maps.Values(unaccountedKeys), bytes.Compare) { + keys := maps.Values(unaccountedKeys) + slices.SortFunc(keys, bytes.Compare) + for _, e := range keys { log.Error(fmt.Sprintf(" example key: %x", e)) } } diff --git a/core/state/snapshot/difflayer.go b/core/state/snapshot/difflayer.go index 28957051d4..dce4f79a11 100644 --- a/core/state/snapshot/difflayer.go +++ b/core/state/snapshot/difflayer.go @@ -19,7 +19,6 @@ package snapshot import ( "encoding/binary" "fmt" - "maps" "math" "math/rand" "slices" @@ -31,6 +30,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/rlp" bloomfilter "github.com/holiman/bloomfilter/v2" + "golang.org/x/exp/maps" ) var ( @@ -431,7 +431,8 @@ func (dl *diffLayer) AccountList() []common.Hash { dl.lock.Lock() defer dl.lock.Unlock() - dl.accountList = slices.SortedFunc(maps.Keys(dl.accountData), common.Hash.Cmp) + dl.accountList = maps.Keys(dl.accountData) + slices.SortFunc(dl.accountList, common.Hash.Cmp) dl.memory += uint64(len(dl.accountList) * common.HashLength) return dl.accountList } @@ -463,7 +464,8 @@ func (dl *diffLayer) StorageList(accountHash common.Hash) []common.Hash { dl.lock.Lock() defer dl.lock.Unlock() - storageList := slices.SortedFunc(maps.Keys(dl.storageData[accountHash]), common.Hash.Cmp) + storageList := maps.Keys(dl.storageData[accountHash]) + slices.SortFunc(storageList, common.Hash.Cmp) dl.storageList[accountHash] = storageList dl.memory += uint64(len(dl.storageList)*common.HashLength + common.HashLength) return storageList diff --git a/core/txpool/blobpool/evictheap.go b/core/txpool/blobpool/evictheap.go index 722a71bc9b..5e285e6c53 100644 --- a/core/txpool/blobpool/evictheap.go +++ b/core/txpool/blobpool/evictheap.go @@ -18,12 +18,12 @@ package blobpool import ( "container/heap" - "maps" "math" "slices" "github.com/ethereum/go-ethereum/common" "github.com/holiman/uint256" + "golang.org/x/exp/maps" ) // evictHeap is a helper data structure to keep track of the cheapest bottleneck @@ -54,7 +54,8 @@ func newPriceHeap(basefee *uint256.Int, blobfee *uint256.Int, index map[common.A // Populate the heap in account sort order. Not really needed in practice, // but it makes the heap initialization deterministic and less annoying to // test in unit tests. - heap.addrs = slices.SortedFunc(maps.Keys(index), common.Address.Cmp) + heap.addrs = maps.Keys(index) + slices.SortFunc(heap.addrs, common.Address.Cmp) for i, addr := range heap.addrs { heap.index[addr] = i } diff --git a/core/txpool/legacypool/legacypool.go b/core/txpool/legacypool/legacypool.go index 7bf360ff65..6ae309a74d 100644 --- a/core/txpool/legacypool/legacypool.go +++ b/core/txpool/legacypool/legacypool.go @@ -19,7 +19,6 @@ package legacypool import ( "errors" - "maps" "math" "math/big" "slices" @@ -42,6 +41,7 @@ import ( "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" "github.com/holiman/uint256" + "golang.org/x/exp/maps" ) const ( @@ -1724,7 +1724,7 @@ func (as *accountSet) addTx(tx *types.Transaction) { // reuse. The returned slice should not be changed! func (as *accountSet) flatten() []common.Address { if as.cache == nil { - as.cache = slices.Collect(maps.Keys(as.accounts)) + as.cache = maps.Keys(as.accounts) } return as.cache } diff --git a/p2p/netutil/net.go b/p2p/netutil/net.go index 696c331859..7d8da88670 100644 --- a/p2p/netutil/net.go +++ b/p2p/netutil/net.go @@ -21,11 +21,12 @@ import ( "bytes" "errors" "fmt" - "maps" "net" "net/netip" "slices" "strings" + + "golang.org/x/exp/maps" ) var special4, special6 Netlist @@ -323,7 +324,8 @@ func (s *DistinctNetSet) key(ip netip.Addr) netip.Prefix { // String implements fmt.Stringer func (s DistinctNetSet) String() string { - keys := slices.SortedFunc(maps.Keys(s.members), func(a, b netip.Prefix) int { + keys := maps.Keys(s.members) + slices.SortFunc(keys, func(a, b netip.Prefix) int { return strings.Compare(a.String(), b.String()) }) diff --git a/triedb/pathdb/history.go b/triedb/pathdb/history.go index c063e45371..dd0b2080a3 100644 --- a/triedb/pathdb/history.go +++ b/triedb/pathdb/history.go @@ -21,7 +21,6 @@ import ( "encoding/binary" "errors" "fmt" - "maps" "slices" "time" @@ -30,6 +29,7 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" + "golang.org/x/exp/maps" ) // State history records the state changes involved in executing a block. The @@ -250,11 +250,15 @@ type history struct { // newHistory constructs the state history object with provided state change set. func newHistory(root common.Hash, parent common.Hash, block uint64, accounts map[common.Address][]byte, storages map[common.Address]map[common.Hash][]byte, rawStorageKey bool) *history { var ( - accountList = slices.SortedFunc(maps.Keys(accounts), common.Address.Cmp) + accountList = maps.Keys(accounts) storageList = make(map[common.Address][]common.Hash) ) + slices.SortFunc(accountList, common.Address.Cmp) + for addr, slots := range storages { - storageList[addr] = slices.SortedFunc(maps.Keys(slots), common.Hash.Cmp) + addrs := maps.Keys(slots) + slices.SortFunc(addrs, common.Hash.Cmp) + storageList[addr] = addrs } version := historyVersion if !rawStorageKey { diff --git a/triedb/pathdb/states.go b/triedb/pathdb/states.go index 0a83b2f2cc..873a7ba618 100644 --- a/triedb/pathdb/states.go +++ b/triedb/pathdb/states.go @@ -19,7 +19,6 @@ package pathdb import ( "fmt" "io" - "maps" "slices" "sync" @@ -28,6 +27,7 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/rlp" + "golang.org/x/exp/maps" ) // counter helps in tracking items and their corresponding sizes. @@ -174,7 +174,8 @@ func (s *stateSet) accountList() []common.Hash { s.listLock.Lock() defer s.listLock.Unlock() - list = slices.SortedFunc(maps.Keys(s.accountData), common.Hash.Cmp) + list = maps.Keys(s.accountData) + slices.SortFunc(list, common.Hash.Cmp) s.accountListSorted = list return list } @@ -204,7 +205,8 @@ func (s *stateSet) storageList(accountHash common.Hash) []common.Hash { s.listLock.Lock() defer s.listLock.Unlock() - list := slices.SortedFunc(maps.Keys(s.storageData[accountHash]), common.Hash.Cmp) + list := maps.Keys(s.storageData[accountHash]) + slices.SortFunc(list, common.Hash.Cmp) s.storageListSorted[accountHash] = list return list }