Skip to content
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

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

Merged
merged 8 commits into from
Aug 25, 2023

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

core/types/hashing.go Outdated Show resolved Hide resolved
@fjl
Copy link
Contributor Author

fjl commented Aug 23, 2023

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

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.
core/types/receipt.go Outdated Show resolved Hide resolved
core/types/receipt.go Outdated Show resolved Hide resolved
@fjl fjl merged commit 9bbb9df into ethereum:master Aug 25, 2023
1 of 2 checks passed
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 <martin@swende.se>
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.
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