rlp: reduce allocations for big.Int and byte array encoding (#21291)

This change further improves the performance of RLP encoding by removing
allocations for big.Int and [...]byte types. I have added a new benchmark
that measures RLP encoding of types.Block to verify that performance is
improved.
This commit is contained in:
Felix Lange
2020-07-06 11:17:09 +02:00
committed by GitHub
parent fa01117498
commit 6315b6fcc0
4 changed files with 222 additions and 43 deletions

View File

@ -23,6 +23,9 @@ import (
"testing"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp"
)
@ -72,10 +75,58 @@ func TestUncleHash(t *testing.T) {
t.Fatalf("empty uncle hash is wrong, got %x != %x", h, exp)
}
}
func BenchmarkUncleHash(b *testing.B) {
uncles := make([]*Header, 0)
var benchBuffer = bytes.NewBuffer(make([]byte, 0, 32000))
func BenchmarkEncodeBlock(b *testing.B) {
block := makeBenchBlock()
b.ResetTimer()
for i := 0; i < b.N; i++ {
CalcUncleHash(uncles)
benchBuffer.Reset()
if err := rlp.Encode(benchBuffer, block); err != nil {
b.Fatal(err)
}
}
}
func makeBenchBlock() *Block {
var (
key, _ = crypto.GenerateKey()
txs = make([]*Transaction, 70)
receipts = make([]*Receipt, len(txs))
signer = NewEIP155Signer(params.TestChainConfig.ChainID)
uncles = make([]*Header, 3)
)
header := &Header{
Difficulty: math.BigPow(11, 11),
Number: math.BigPow(2, 9),
GasLimit: 12345678,
GasUsed: 1476322,
Time: 9876543,
Extra: []byte("coolest block on chain"),
}
for i := range txs {
amount := math.BigPow(2, int64(i))
price := big.NewInt(300000)
data := make([]byte, 100)
tx := NewTransaction(uint64(i), common.Address{}, amount, 123457, price, data)
signedTx, err := SignTx(tx, signer, key)
if err != nil {
panic(err)
}
txs[i] = signedTx
receipts[i] = NewReceipt(make([]byte, 32), false, tx.Gas())
}
for i := range uncles {
uncles[i] = &Header{
Difficulty: math.BigPow(11, 11),
Number: math.BigPow(2, 9),
GasLimit: 12345678,
GasUsed: 1476322,
Time: 9876543,
Extra: []byte("benchmark uncle"),
}
}
return NewBlock(header, txs, uncles, receipts)
}