diff --git a/core/txpool/lending_tx_list.go b/core/txpool/lending_tx_list.go index d7c30cea595..e38f212011c 100644 --- a/core/txpool/lending_tx_list.go +++ b/core/txpool/lending_tx_list.go @@ -18,6 +18,7 @@ package txpool import ( "container/heap" + "slices" "sort" "github.com/XinFinOrg/XDPoSChain/core/types" @@ -108,13 +109,14 @@ func (m *lendingtxSortedMap) Cap(threshold int) types.LendingTransactions { // Otherwise gather and drop the highest nonce'd transactions var drops types.LendingTransactions - sort.Sort(*m.index) + slices.Sort(*m.index) for size := len(m.items); size > threshold; size-- { drops = append(drops, m.items[(*m.index)[size-1]]) delete(m.items, (*m.index)[size-1]) } *m.index = (*m.index)[:threshold] - heap.Init(m.index) + // The sorted m.index slice is still a valid heap, so there is no need to + // reheap after deleting tail items. // If we had a cache, shift the back if m.cache != nil { diff --git a/core/txpool/list.go b/core/txpool/list.go index 50eebf152a6..26a337d01fa 100644 --- a/core/txpool/list.go +++ b/core/txpool/list.go @@ -20,6 +20,7 @@ import ( "container/heap" "math" "math/big" + "slices" "sort" "sync" "sync/atomic" @@ -150,13 +151,14 @@ func (m *sortedMap) Cap(threshold int) types.Transactions { // Otherwise gather and drop the highest nonce'd transactions var drops types.Transactions - sort.Sort(*m.index) + slices.Sort(*m.index) for size := len(m.items); size > threshold; size-- { drops = append(drops, m.items[(*m.index)[size-1]]) delete(m.items, (*m.index)[size-1]) } *m.index = (*m.index)[:threshold] - heap.Init(m.index) + // The sorted m.index slice is still a valid heap, so there is no need to + // reheap after deleting tail items. // If we had a cache, shift the back if m.cache != nil { diff --git a/core/txpool/list_test.go b/core/txpool/list_test.go index 10fe2c94056..39e809b0107 100644 --- a/core/txpool/list_test.go +++ b/core/txpool/list_test.go @@ -68,3 +68,24 @@ func BenchmarkListAdd(t *testing.B) { list.Filter(priceLimit, DefaultConfig.PriceBump, nil, nil) } } + +func BenchmarkListCapOneTx(b *testing.B) { + // Generate a list of transactions to insert + key, _ := crypto.GenerateKey() + + txs := make(types.Transactions, 32) + for i := 0; i < len(txs); i++ { + txs[i] = transaction(uint64(i), 0, key) + } + + for b.Loop() { + list := newList(true) + // Insert the transactions in a random order + for _, v := range rand.Perm(len(txs)) { + list.Add(txs[v], DefaultConfig.PriceBump) + } + b.StartTimer() + list.Cap(list.Len() - 1) + b.StopTimer() + } +} diff --git a/core/txpool/order_tx_list.go b/core/txpool/order_tx_list.go index 60df14e8586..4efdef04f89 100644 --- a/core/txpool/order_tx_list.go +++ b/core/txpool/order_tx_list.go @@ -18,6 +18,7 @@ package txpool import ( "container/heap" + "slices" "sort" "github.com/XinFinOrg/XDPoSChain/core/types" @@ -108,13 +109,14 @@ func (m *ordertxSortedMap) Cap(threshold int) types.OrderTransactions { // Otherwise gather and drop the highest nonce'd transactions var drops types.OrderTransactions - sort.Sort(*m.index) + slices.Sort(*m.index) for size := len(m.items); size > threshold; size-- { drops = append(drops, m.items[(*m.index)[size-1]]) delete(m.items, (*m.index)[size-1]) } *m.index = (*m.index)[:threshold] - heap.Init(m.index) + // The sorted m.index slice is still a valid heap, so there is no need to + // reheap after deleting tail items. // If we had a cache, shift the back if m.cache != nil {