mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-19 05:11:37 +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 {
|
for accountHash := range diff.states.accountData {
|
||||||
list, exists := l.accounts[accountHash]
|
list, exists := l.accounts[accountHash]
|
||||||
if !exists {
|
if !exists {
|
||||||
list = make([]common.Hash, 0, 16) // TODO(rjl493456442) use sync pool
|
list = getHashList()
|
||||||
}
|
}
|
||||||
list = append(list, state)
|
list = append(list, state)
|
||||||
l.accounts[accountHash] = list
|
l.accounts[accountHash] = list
|
||||||
|
|
@ -204,7 +204,7 @@ func (l *lookup) addLayer(diff *diffLayer) {
|
||||||
key := storageKey(accountHash, slotHash)
|
key := storageKey(accountHash, slotHash)
|
||||||
list, exists := l.storages[key]
|
list, exists := l.storages[key]
|
||||||
if !exists {
|
if !exists {
|
||||||
list = make([]common.Hash, 0, 16) // TODO(rjl493456442) use sync pool
|
list = getHashList()
|
||||||
}
|
}
|
||||||
list = append(list, state)
|
list = append(list, state)
|
||||||
l.storages[key] = list
|
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.
|
// Mitigation: release the array if capacity exceeds threshold.
|
||||||
list = list[1:]
|
list = list[1:]
|
||||||
if cap(list) > 1024 {
|
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
|
return true, list
|
||||||
|
|
@ -258,6 +260,7 @@ func (l *lookup) removeLayer(diff *diffLayer) error {
|
||||||
if len(list) != 0 {
|
if len(list) != 0 {
|
||||||
l.accounts[accountHash] = list
|
l.accounts[accountHash] = list
|
||||||
} else {
|
} else {
|
||||||
|
putHashList(list)
|
||||||
delete(l.accounts, accountHash)
|
delete(l.accounts, accountHash)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -275,6 +278,7 @@ func (l *lookup) removeLayer(diff *diffLayer) error {
|
||||||
if len(list) != 0 {
|
if len(list) != 0 {
|
||||||
l.storages[key] = list
|
l.storages[key] = list
|
||||||
} else {
|
} else {
|
||||||
|
putHashList(list)
|
||||||
delete(l.storages, key)
|
delete(l.storages, key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -283,3 +287,24 @@ func (l *lookup) removeLayer(diff *diffLayer) error {
|
||||||
})
|
})
|
||||||
return eg.Wait()
|
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