-
Couldn't load subscription status.
- Fork 21.5k
core/rawdb: reduce allocations in *key methods #33006
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
core/rawdb: reduce allocations in *key methods #33006
Conversation
|
Pls don't merge yet, I have some more improvements in the pipeline |
|
Benchmark func BenchmarkKeys(b *testing.B) {
l := common.Hash{1}
m := common.Hash{2}
number := uint64(123)
number32 := uint32(123)
path := []byte{1, 2, 3}
b.Run("headerNumberKey", func(b *testing.B) {
fn := func() []byte { return headerNumberKey(l) }
for range b.N {
fn()
}
})
b.Run("headerHashKey", func(b *testing.B) {
fn := func() []byte { return headerHashKey(number) }
for range b.N {
fn()
}
})
b.Run("blockBodyKey", func(b *testing.B) {
fn := func() []byte { return blockBodyKey(number, l) }
for range b.N {
fn()
}
})
b.Run("blockReceiptsKey", func(b *testing.B) {
fn := func() []byte { return blockReceiptsKey(number, l) }
for range b.N {
fn()
}
})
b.Run("txLookupKey", func(b *testing.B) {
fn := func() []byte { return txLookupKey(l) }
for range b.N {
fn()
}
})
b.Run("accountSnapshotKey", func(b *testing.B) {
fn := func() []byte { return accountSnapshotKey(l) }
for range b.N {
fn()
}
})
b.Run("storageSnapshotKey", func(b *testing.B) {
fn := func() []byte { return storageSnapshotKey(l, m) }
for range b.N {
fn()
}
})
b.Run("storageSnapshotsKey", func(b *testing.B) {
fn := func() []byte { return storageSnapshotsKey(l) }
for range b.N {
fn()
}
})
b.Run("skeletonHeaderKey", func(b *testing.B) {
fn := func() []byte { return skeletonHeaderKey(number) }
for range b.N {
fn()
}
})
b.Run("preimageKey", func(b *testing.B) {
fn := func() []byte { return preimageKey(l) }
for range b.N {
fn()
}
})
b.Run("codeKey", func(b *testing.B) {
fn := func() []byte { return codeKey(l) }
for range b.N {
fn()
}
})
b.Run("configKey", func(b *testing.B) {
fn := func() []byte { return configKey(l) }
for range b.N {
fn()
}
})
b.Run("genesisStateSpecKey", func(b *testing.B) {
fn := func() []byte { return genesisStateSpecKey(l) }
for range b.N {
fn()
}
})
b.Run("stateIDKey", func(b *testing.B) {
fn := func() []byte { return stateIDKey(l) }
for range b.N {
fn()
}
})
b.Run("accountTrieNodeKey", func(b *testing.B) {
fn := func() []byte { return accountTrieNodeKey(path) }
for range b.N {
fn()
}
})
b.Run("storageTrieNodeKey", func(b *testing.B) {
fn := func() []byte { return storageTrieNodeKey(l, path) }
for range b.N {
fn()
}
})
b.Run("filterMapRowKey", func(b *testing.B) {
fn := func() []byte { return filterMapRowKey(number, true) }
for range b.N {
fn()
}
})
b.Run("filterMapLastBlockKey", func(b *testing.B) {
fn := func() []byte { return filterMapLastBlockKey(number32) }
for range b.N {
fn()
}
})
b.Run("filterMapBlockLVKey", func(b *testing.B) {
fn := func() []byte { return filterMapBlockLVKey(number) }
for range b.N {
fn()
}
})
b.Run("accountHistoryIndexKey", func(b *testing.B) {
fn := func() []byte { return accountHistoryIndexKey(l) }
for range b.N {
fn()
}
})
b.Run("storageHistoryIndexKey", func(b *testing.B) {
fn := func() []byte { return storageHistoryIndexKey(l, m) }
for range b.N {
fn()
}
})
b.Run("trienodeHistoryIndexKey", func(b *testing.B) {
fn := func() []byte { return trienodeHistoryIndexKey(l, path) }
for range b.N {
fn()
}
})
b.Run("accountHistoryIndexBlockKey", func(b *testing.B) {
fn := func() []byte { return accountHistoryIndexBlockKey(l, number32) }
for range b.N {
fn()
}
})
b.Run("storageHistoryIndexBlockKey", func(b *testing.B) {
fn := func() []byte { return storageHistoryIndexBlockKey(l, m, number32) }
for range b.N {
fn()
}
})
b.Run("trienodeHistoryIndexBlockKey", func(b *testing.B) {
fn := func() []byte { return trienodeHistoryIndexBlockKey(l, path, number32) }
for range b.N {
fn()
}
})
b.Run("transitionStateKey", func(b *testing.B) {
fn := func() []byte { return transitionStateKey(l) }
for range b.N {
fn()
}
})
} |
|
We could even reduce the allocations of the path based methods, by allocating a fixed size array longer than the key and cutting it down to the key length, but for that I would need to know the maximum key length cc @rjl493456442 |
Reduces the allocation in certain methods. This will reduce overall allocations by 5-10% during snap sync.
The issue is that the compiler does not know that the keys are const, thus it can't allocate the keys on the stack.
All methods that take in var length parameters, e.g
trienodeHistoryIndexKeycan't be optimized like this, since the compiler does not know thatpathis only of a certain size