Skip to content

Conversation

fjl
Copy link
Contributor

@fjl fjl commented Aug 22, 2023

Just some minor optimizations I figured out a while ago. By using ReadBytes instead of
Bytes on the rlp stream, we can save the allocation of a temporary buffer for the typed tx
payload.

@fjl fjl added this to the 1.13.0 milestone Aug 22, 2023
@fjl
Copy link
Contributor Author

fjl commented Aug 22, 2023

I'm not really sure about these benchmark results. Will rerun on another machine to verify.

@fjl
Copy link
Contributor Author

fjl commented Aug 22, 2023

Here are some more stable results. It looks like the effect of this change is very minimal:

goos: freebsd
goarch: amd64
pkg: github.com/ethereum/go-ethereum/core/types
cpu: Intel(R) Core(TM) i7-7700 CPU @ 3.60GHz
                                │ types.old.txt │            types.new.txt            │
                                │    sec/op     │    sec/op     vs base               │
EncodeRLP/legacy-header-6          242.1n ±  1%   239.2n ±  1%  -1.24% (p=0.000 n=10)
EncodeRLP/london-header-6          252.7n ±  1%   250.6n ±  1%  -0.81% (p=0.006 n=10)
EncodeRLP/receipt-for-storage-6    128.9n ±  0%   124.3n ±  0%  -3.64% (p=0.000 n=10)
EncodeRLP/receipt-full-6           303.6n ±  0%   305.3n ±  1%  +0.54% (p=0.000 n=10)
EncodeRLP/legacy-transaction-6     405.3n ±  1%   379.9n ±  0%  -6.27% (p=0.000 n=10)
EncodeRLP/access-transaction-6     607.3n ±  0%   590.9n ±  0%  -2.71% (p=0.000 n=10)
EncodeRLP/1559-transaction-6       591.8n ±  0%   581.2n ±  0%  -1.79% (p=0.000 n=10)
DecodeRLP/legacy-header-6          931.0n ±  0%   930.0n ±  0%  -0.12% (p=0.000 n=10)
DecodeRLP/london-header-6          953.2n ±  0%   950.5n ±  0%  -0.28% (p=0.000 n=10)
DecodeRLP/receipt-for-storage-6    506.2n ±  4%   514.0n ±  5%       ~ (p=0.353 n=10)
DecodeRLP/receipt-full-6           585.3n ±  2%   586.6n ±  4%  +0.23% (p=0.010 n=10)
DecodeRLP/legacy-transaction-6     1.278µ ± 10%   1.252µ ± 13%       ~ (p=0.869 n=10)
DecodeRLP/access-transaction-6     1.507µ ±  9%   1.555µ ±  5%       ~ (p=0.564 n=10)
DecodeRLP/1559-transaction-6       1.710µ ±  9%   1.635µ ±  9%       ~ (p=0.325 n=10)
geomean                            560.5n         553.2n        -1.30%

                                │ types.old.txt │            types.new.txt             │
                                │      B/s      │      B/s       vs base               │
EncodeRLP/legacy-header-6          2.089Gi ± 1%   2.115Gi ±  1%  +1.25% (p=0.000 n=10)
EncodeRLP/london-header-6          2.023Gi ± 1%   2.040Gi ±  1%  +0.81% (p=0.007 n=10)
EncodeRLP/receipt-for-storage-6    66.55Mi ± 0%   69.10Mi ±  0%  +3.83% (p=0.000 n=10)
EncodeRLP/receipt-full-6           848.1Mi ± 0%   843.5Mi ±  1%  -0.53% (p=0.000 n=10)
EncodeRLP/legacy-transaction-6     240.0Mi ± 1%   256.0Mi ±  0%  +6.69% (p=0.000 n=10)
EncodeRLP/access-transaction-6     166.4Mi ± 0%   171.1Mi ±  0%  +2.79% (p=0.000 n=10)
EncodeRLP/1559-transaction-6       177.3Mi ± 0%   180.5Mi ±  0%  +1.82% (p=0.000 n=10)
DecodeRLP/legacy-header-6          556.2Mi ± 0%   556.9Mi ±  0%  +0.12% (p=0.000 n=10)
DecodeRLP/london-header-6          549.3Mi ± 0%   550.8Mi ±  0%  +0.28% (p=0.000 n=10)
DecodeRLP/receipt-for-storage-6    16.96Mi ± 3%   16.70Mi ±  5%       ~ (p=0.362 n=10)
DecodeRLP/receipt-full-6           439.9Mi ± 2%   438.9Mi ±  4%  -0.23% (p=0.011 n=10)
DecodeRLP/legacy-transaction-6     76.14Mi ± 9%   77.70Mi ± 11%       ~ (p=0.912 n=10)
DecodeRLP/access-transaction-6     67.10Mi ± 8%   64.99Mi ±  4%       ~ (p=0.579 n=10)
DecodeRLP/1559-transaction-6       61.39Mi ± 8%   64.18Mi ±  8%       ~ (p=0.325 n=10)
geomean                            231.4Mi        234.5Mi        +1.31%

                                │ types.old.txt │            types.new.txt             │
                                │     B/op      │    B/op     vs base                  │
EncodeRLP/legacy-header-6          0.000 ± 0%     0.000 ± 0%        ~ (p=1.000 n=10) ¹
EncodeRLP/london-header-6          0.000 ± 0%     0.000 ± 0%        ~ (p=1.000 n=10) ¹
EncodeRLP/receipt-for-storage-6    0.000 ± 0%     0.000 ± 0%        ~ (p=1.000 n=10) ¹
EncodeRLP/receipt-full-6           320.0 ± 0%     320.0 ± 0%        ~ (p=1.000 n=10) ¹
EncodeRLP/legacy-transaction-6     0.000 ± 0%     0.000 ± 0%        ~ (p=1.000 n=10) ¹
EncodeRLP/access-transaction-6     24.00 ± 0%     24.00 ± 0%        ~ (p=1.000 n=10) ¹
EncodeRLP/1559-transaction-6       24.00 ± 0%     24.00 ± 0%        ~ (p=1.000 n=10) ¹
DecodeRLP/legacy-header-6          112.0 ± 0%     112.0 ± 0%        ~ (p=1.000 n=10) ¹
DecodeRLP/london-header-6          112.0 ± 0%     112.0 ± 0%        ~ (p=1.000 n=10) ¹
DecodeRLP/receipt-for-storage-6    144.0 ± 0%     144.0 ± 0%        ~ (p=1.000 n=10) ¹
DecodeRLP/receipt-full-6           393.0 ± 0%     393.0 ± 0%        ~ (p=1.000 n=10) ¹
DecodeRLP/legacy-transaction-6     480.0 ± 0%     480.0 ± 0%        ~ (p=1.000 n=10) ¹
DecodeRLP/access-transaction-6     736.0 ± 0%     624.0 ± 0%  -15.22% (p=0.000 n=10)
DecodeRLP/1559-transaction-6       768.0 ± 0%     656.0 ± 0%  -14.58% (p=0.000 n=10)
geomean                                       ²                -2.28%                ²
¹ all samples are equal
² summaries must be >0 to compute geomean

                                │ types.old.txt │            types.new.txt            │
                                │   allocs/op   │ allocs/op   vs base                 │
EncodeRLP/legacy-header-6          0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=10) ¹
EncodeRLP/london-header-6          0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=10) ¹
EncodeRLP/receipt-for-storage-6    0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=10) ¹
EncodeRLP/receipt-full-6           1.000 ± 0%     1.000 ± 0%       ~ (p=1.000 n=10) ¹
EncodeRLP/legacy-transaction-6     0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=10) ¹
EncodeRLP/access-transaction-6     1.000 ± 0%     1.000 ± 0%       ~ (p=1.000 n=10) ¹
EncodeRLP/1559-transaction-6       1.000 ± 0%     1.000 ± 0%       ~ (p=1.000 n=10) ¹
DecodeRLP/legacy-header-6          3.000 ± 0%     3.000 ± 0%       ~ (p=1.000 n=10) ¹
DecodeRLP/london-header-6          3.000 ± 0%     3.000 ± 0%       ~ (p=1.000 n=10) ¹
DecodeRLP/receipt-for-storage-6    5.000 ± 0%     5.000 ± 0%       ~ (p=1.000 n=10) ¹
DecodeRLP/receipt-full-6           4.000 ± 0%     4.000 ± 0%       ~ (p=1.000 n=10) ¹
DecodeRLP/legacy-transaction-6     13.00 ± 0%     13.00 ± 0%       ~ (p=1.000 n=10) ¹
DecodeRLP/access-transaction-6     18.00 ± 0%     17.00 ± 0%  -5.56% (p=0.000 n=10)
DecodeRLP/1559-transaction-6       19.00 ± 0%     18.00 ± 0%  -5.26% (p=0.000 n=10)
geomean                                       ²               -0.79%                ²
¹ all samples are equal
² summaries must be >0 to compute geomean

@fjl fjl force-pushed the core-types-opt-2 branch from 4da936d to 7269980 Compare August 23, 2023 12:59
@fjl
Copy link
Contributor Author

fjl commented Aug 23, 2023

This should be ready now. The package rlp change has moved to #27987

fjl added 7 commits August 23, 2023 22:07
Since the first three fields of Log are the ones that should appear in the canon encoding,
we can simply ignore the remaining fields via struct tag. Doing this removes an
indirection through the rlpLog type.
If kind == rlp.Byte, the size reported by Stream.Kind will be zero, but we need a buffer
of size 1 for ReadBytes. Since typed txs always have to be longer than 1 byte, we can just
return an error for kind == rlp.Byte.
@fjl fjl force-pushed the core-types-opt-2 branch from 7269980 to 8e72579 Compare August 23, 2023 20:07
@fjl fjl merged commit 9bbb9df into ethereum:master Aug 25, 2023
devopsbo3 pushed a commit to HorizenOfficial/go-ethereum that referenced this pull request Nov 10, 2023
…thereum#27976)

Just some minor optimizations I figured out a while ago. By using ReadBytes instead of
Bytes on the rlp stream, we can save the allocation of a temporary buffer for the typed tx
payload.

If kind == rlp.Byte, the size reported by Stream.Kind will be zero, but we need a buffer
of size 1 for ReadBytes. Since typed txs always have to be longer than 1 byte, we can just
return an error for kind == rlp.Byte.

There is a also a small change for Log: since the first three fields of Log are the ones that 
should appear in the canon encoding, we can simply ignore the remaining fields via 
struct tag. Doing this removes an indirection through the rlpLog type.

---------

Co-authored-by: Martin Holst Swende <[email protected]>
devopsbo3 added a commit to HorizenOfficial/go-ethereum that referenced this pull request Nov 10, 2023
devopsbo3 added a commit to HorizenOfficial/go-ethereum that referenced this pull request Nov 10, 2023
sduchesneau pushed a commit to streamingfast/go-ethereum that referenced this pull request Feb 26, 2024
core/types: transaction and receipt encoding/decoding optimizations

 Conflicts:
  core/types/transaction.go
conflict due to us adding a parameter to decodeTyped function. Added
both changes.
pdrobnjak pushed a commit to Tenderly/net-scroll-geth that referenced this pull request Apr 30, 2025
* upgrade rlp to go-ethereum v.14.6

* core/types: transaction and receipt encoding/decoding optimizations ethereum#27976

* core/types: use new atomic types in caches ethereum#29411, fix eth/handler bug

* eth/fetcher: throttle peers which deliver many invalid transactions ethereum#25573

* core: preallocate map in tx_pool ethereum#25737

* core/txpool: protect cache with mutex ethereum#27898

* upgrade memsize to v0.0.2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants