mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-12 01:41:36 +00:00
Merge b066812373 into a8ea6319f1
This commit is contained in:
commit
6f23314add
2 changed files with 42 additions and 3 deletions
|
|
@ -916,3 +916,17 @@ func TestStorageLookup(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// goos: darwin
|
||||
// goarch: arm64
|
||||
// pkg: github.com/ethereum/go-ethereum/triedb/pathdb
|
||||
// cpu: Apple M1 Pro
|
||||
// BenchmarkHashList
|
||||
// BenchmarkHashList-8 52540634 22.61 ns/op 24 B/op 1 allocs/op
|
||||
func BenchmarkHashList(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
for i := 0; i < b.N; i++ {
|
||||
l := getHashList()
|
||||
putHashList(l)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -189,7 +189,7 @@ func (l *lookup) addLayer(diff *diffLayer) {
|
|||
for accountHash := range diff.states.accountData {
|
||||
list, exists := l.accounts[accountHash]
|
||||
if !exists {
|
||||
list = make([]common.Hash, 0, 16) // TODO(rjl493456442) use sync pool
|
||||
list = getHashList()
|
||||
}
|
||||
list = append(list, state)
|
||||
l.accounts[accountHash] = list
|
||||
|
|
@ -204,7 +204,7 @@ func (l *lookup) addLayer(diff *diffLayer) {
|
|||
key := storageKey(accountHash, slotHash)
|
||||
list, exists := l.storages[key]
|
||||
if !exists {
|
||||
list = make([]common.Hash, 0, 16) // TODO(rjl493456442) use sync pool
|
||||
list = getHashList()
|
||||
}
|
||||
list = append(list, state)
|
||||
l.storages[key] = list
|
||||
|
|
@ -229,7 +229,9 @@ func removeFromList(list []common.Hash, element common.Hash) (bool, []common.Has
|
|||
// Mitigation: release the array if capacity exceeds threshold.
|
||||
list = list[1:]
|
||||
if cap(list) > 1024 {
|
||||
list = append(make([]common.Hash, 0, len(list)), list...)
|
||||
newList := append(make([]common.Hash, 0, len(list)), list...)
|
||||
putHashList(list)
|
||||
list = newList
|
||||
}
|
||||
}
|
||||
return true, list
|
||||
|
|
@ -258,6 +260,7 @@ func (l *lookup) removeLayer(diff *diffLayer) error {
|
|||
if len(list) != 0 {
|
||||
l.accounts[accountHash] = list
|
||||
} else {
|
||||
putHashList(list)
|
||||
delete(l.accounts, accountHash)
|
||||
}
|
||||
}
|
||||
|
|
@ -275,6 +278,7 @@ func (l *lookup) removeLayer(diff *diffLayer) error {
|
|||
if len(list) != 0 {
|
||||
l.storages[key] = list
|
||||
} else {
|
||||
putHashList(list)
|
||||
delete(l.storages, key)
|
||||
}
|
||||
}
|
||||
|
|
@ -283,3 +287,24 @@ func (l *lookup) removeLayer(diff *diffLayer) error {
|
|||
})
|
||||
return eg.Wait()
|
||||
}
|
||||
|
||||
// hashListPool is not allocation-free. Since a slice header is 24 bytes and
|
||||
// cannot be stored directly in an interface, interface boxing is involved,
|
||||
// which typically incurs a 24-byte allocation. This design strikes a balance
|
||||
// between allocation efficiency and code simplicity. Note that it is possible
|
||||
// to achieve zero allocations by wrapping the []common.Hash in a struct and
|
||||
// storing a pointer to that struct in the sync.Pool.
|
||||
var hashListPool = sync.Pool{
|
||||
New: func() any {
|
||||
return make([]common.Hash, 0, 16)
|
||||
},
|
||||
}
|
||||
|
||||
func getHashList() []common.Hash {
|
||||
l := hashListPool.Get().([]common.Hash)
|
||||
return l[:0]
|
||||
}
|
||||
|
||||
func putHashList(l []common.Hash) {
|
||||
hashListPool.Put(l)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue