mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-02-26 15:47:21 +00:00
core/vm: improve memory resize (#33056)
Looks like (in some very EVM specific tests) we spent a lot of time
resizing memory. If the underlying array is big enough, we can speed it
up a bit by simply slicing the memory.
goos: linux
goarch: amd64
pkg: github.com/ethereum/go-ethereum/core/vm
cpu: Intel(R) Core(TM) Ultra 7 155U
│ /tmp/old.txt │ /tmp/new.txt │
│ sec/op │ sec/op vs base │
Resize-14 6.145n ± 9% 1.854n ± 14% -69.83% (p=0.000 n=10)
│ /tmp/old.txt │ /tmp/new.txt │
│ B/op │ B/op vs base │
Resize-14 5.000 ± 0% 5.000 ± 0% ~ (p=1.000 n=10)
│ /tmp/old.txt │ /tmp/new.txt │
│ allocs/op │ allocs/op vs base │
Resize-14 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹
From the blocktest benchmark:
620ms 10.93s (flat, cum) 9.92% of Total
. . 80:func (m *Memory) Resize(size uint64) {
30ms 60ms 81: if uint64(m.Len()) < size {
590ms 10.87s 82: m.store = append(m.store, make([]byte, size-uint64(m.Len()))...)
. . 83: }
. . 84:}
---------
Co-authored-by: Felix Lange <fjl@twurst.com>
This commit is contained in:
parent
c55a12197e
commit
3bbf5f5b6a
2 changed files with 15 additions and 3 deletions
|
|
@ -44,6 +44,7 @@ func (m *Memory) Free() {
|
|||
// To reduce peak allocation, return only smaller memory instances to the pool.
|
||||
const maxBufferSize = 16 << 10
|
||||
if cap(m.store) <= maxBufferSize {
|
||||
clear(m.store)
|
||||
m.store = m.store[:0]
|
||||
m.lastGasCost = 0
|
||||
memoryPool.Put(m)
|
||||
|
|
@ -76,10 +77,14 @@ func (m *Memory) Set32(offset uint64, val *uint256.Int) {
|
|||
val.PutUint256(m.store[offset:])
|
||||
}
|
||||
|
||||
// Resize resizes the memory to size
|
||||
// Resize grows the memory to the requested size.
|
||||
func (m *Memory) Resize(size uint64) {
|
||||
if uint64(m.Len()) < size {
|
||||
m.store = append(m.store, make([]byte, size-uint64(m.Len()))...)
|
||||
if uint64(len(m.store)) < size {
|
||||
if uint64(cap(m.store)) >= size {
|
||||
m.store = m.store[:size]
|
||||
} else {
|
||||
m.store = append(m.store, make([]byte, size-uint64(len(m.store)))...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -83,3 +83,10 @@ func TestMemoryCopy(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkResize(b *testing.B) {
|
||||
memory := NewMemory()
|
||||
for i := range b.N {
|
||||
memory.Resize(uint64(i))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue