Skip to content

Commit 0045267

Browse files
core/txpool/legacypool: refactor truncatePending (#31715)
TruncatePending shows up bright red on our nodes, because it computes the length of a map multiple times. I don't know why this is so expensive, but around 20% of our time is spent on this, which is super weird. ``` //PR: BenchmarkTruncatePending-24 17498 69397 ns/op 32872 B/op 3 allocs/op //Master: BenchmarkTruncatePending-24 9960 123954 ns/op 32872 B/op 3 allocs/op ``` ``` benchmark old ns/op new ns/op delta BenchmarkTruncatePending-24 123954 69397 -44.01% benchmark old allocs new allocs delta BenchmarkTruncatePending-24 3 3 +0.00% benchmark old bytes new bytes delta BenchmarkTruncatePending-24 32872 32872 +0.00% ``` This simple PR is a 44% improvement over the old state ``` OUTINE ======================== github.com/ethereum/go-ethereum/core/txpool/legacypool.(*LegacyPool).truncatePending in github.com/ethereum/go-ethereum/core/txpool/legacypool/legacypool.go 1.96s 18.02s (flat, cum) 19.57% of Total . . 1495:func (pool *LegacyPool) truncatePending() { . . 1496: pending := uint64(0) 60ms 2.99s 1497: for _, list := range pool.pending { 250ms 5.48s 1498: pending += uint64(list.Len()) . . 1499: } . . 1500: if pending <= pool.config.GlobalSlots { . . 1501: return . . 1502: } . . 1503: . . 1504: pendingBeforeCap := pending . . 1505: // Assemble a spam order to penalize large transactors first . 510ms 1506: spammers := prque.New[int64, common.Address](nil) 140ms 2.50s 1507: for addr, list := range pool.pending { . . 1508: // Only evict transactions from high rollers 50ms 5.08s 1509: if uint64(list.Len()) > pool.config.AccountSlots { . . 1510: spammers.Push(addr, int64(list.Len())) . . 1511: } . . 1512: } . . 1513: // Gradually drop transactions from offenders . . 1514: offenders := []common.Address{} ``` ```go // Benchmarks the speed of batch transaction insertion in case of multiple accounts. func BenchmarkTruncatePending(b *testing.B) { // Generate a batch of transactions to enqueue into the pool pool, _ := setupPool() defer pool.Close() b.ReportAllocs() batches := make(types.Transactions, 4096+1024+1) for i := range len(batches) { key, _ := crypto.GenerateKey() account := crypto.PubkeyToAddress(key.PublicKey) pool.currentState.AddBalance(account, uint256.NewInt(1000000), tracing.BalanceChangeUnspecified) tx := transaction(uint64(0), 100000, key) batches[i] = tx } for _, tx := range batches { pool.addRemotesSync([]*types.Transaction{tx}) } b.ResetTimer() // benchmark truncating the pending for range b.N { pool.truncatePending() } } ```
1 parent f750117 commit 0045267

File tree

1 file changed

+10
-10
lines changed

1 file changed

+10
-10
lines changed

core/txpool/legacypool/legacypool.go

+10-10
Original file line numberDiff line numberDiff line change
@@ -1494,22 +1494,22 @@ func (pool *LegacyPool) promoteExecutables(accounts []common.Address) []*types.T
14941494
// equal number for all for accounts with many pending transactions.
14951495
func (pool *LegacyPool) truncatePending() {
14961496
pending := uint64(0)
1497-
for _, list := range pool.pending {
1498-
pending += uint64(list.Len())
1499-
}
1500-
if pending <= pool.config.GlobalSlots {
1501-
return
1502-
}
15031497

1504-
pendingBeforeCap := pending
15051498
// Assemble a spam order to penalize large transactors first
1506-
spammers := prque.New[int64, common.Address](nil)
1499+
spammers := prque.New[uint64, common.Address](nil)
15071500
for addr, list := range pool.pending {
15081501
// Only evict transactions from high rollers
1509-
if uint64(list.Len()) > pool.config.AccountSlots {
1510-
spammers.Push(addr, int64(list.Len()))
1502+
length := uint64(list.Len())
1503+
pending += length
1504+
if length > pool.config.AccountSlots {
1505+
spammers.Push(addr, length)
15111506
}
15121507
}
1508+
if pending <= pool.config.GlobalSlots {
1509+
return
1510+
}
1511+
pendingBeforeCap := pending
1512+
15131513
// Gradually drop transactions from offenders
15141514
offenders := []common.Address{}
15151515
for pending > pool.config.GlobalSlots && !spammers.Empty() {

0 commit comments

Comments
 (0)