bitcoin icon indicating copy to clipboard operation
bitcoin copied to clipboard

refactor: Reduce memory copying operations in bech32 encoding/decoding

Open l0rinc opened this issue 1 year ago • 2 comments

Started optimizing the base conversions in TryParseHex, Base58 and IsSpace - this is the next step.

Here I've reduced the memory reallocations and copying operations in bech32 encoding/decoding, resulting in decode being ~26% faster, encode ~33% faster.

make && ./src/bench/bench_bitcoin --filter='Bech32Decode|Bech32Encode' --min-time=1000

Before:

|             ns/byte |              byte/s |    err% |     total | benchmark
|--------------------:|--------------------:|--------:|----------:|:----------
|               11.42 |       87,597,315.00 |    0.1% |      1.10 | `Bech32Decode`
|               24.36 |       41,059,161.36 |    0.1% |      1.07 | `Bech32Encode`

After:

|             ns/byte |              byte/s |    err% |     total | benchmark
|--------------------:|--------------------:|--------:|----------:|:----------
|                9.01 |      110,934,560.81 |    0.1% |      1.10 | `Bech32Decode`
|               18.25 |       54,794,591.49 |    0.1% |      1.10 | `Bech32Encode`

l0rinc avatar Mar 09 '24 13:03 l0rinc

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Code Coverage

For detailed information about the code coverage, see the test coverage report.

Reviews

See the guideline for information on the review process.

Type Reviewers
ACK josibake, sipa, achow101

If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

Conflicts

No conflicts as of last run.

DrahtBot avatar Mar 09 '24 13:03 DrahtBot

Concept ACK

I cherry-picked your last commit into #30047 to get rid of the hardcoded values inside ExpandHRP. Looking at the rest of your commits here, the rest of the changes look great and the benchmark numbers are a nice improvement. Will review more thoroughly this week!

josibake avatar May 11 '24 09:05 josibake

🚧 At least one of the CI tasks failed. Make sure to run all tests locally, according to the documentation.

Possibly this is due to a silent merge conflict (the changes in this pull request being incompatible with the current code in the target branch). If so, make sure to rebase on the latest commit of the target branch.

Leave a comment here, if you need help tracking down a confusing failure.

Debug: https://github.com/bitcoin/bitcoin/runs/25832897694

DrahtBot avatar Jun 05 '24 10:06 DrahtBot

@josibake, now that the cherry-pick was merged, I've rebased and re-measured - the important part of this change was already included in the other PR, the remaining optimizations here are smaller, but also a lot simpler.

l0rinc avatar Jun 05 '24 11:06 l0rinc

ACK https://github.com/bitcoin/bitcoin/pull/29607/commits/07f64177a49f1b6b4d486d10cf67fddfa3c995eb

Verified the benchmark locally. Aside from the speed improvements, this also improves the readability of the code.

josibake avatar Jun 05 '24 11:06 josibake

utACK 07f64177a49f1b6b4d486d10cf67fddfa3c995eb

Making the code more readable is a good reason to make this change, but this code was specifically written to prioritize simplicity over performance. If we'd care about performance, it's probably better to use an approach similar to that of the C reference implementation (as it works entirely on the stack, while the current code does several allocations: 1 in ExpandHRP, between 1 and 3 in CreateChecksum, and 1 inevitable one in Encode).

sipa avatar Jun 05 '24 13:06 sipa

ACK 07f64177a49f1b6b4d486d10cf67fddfa3c995eb

achow101 avatar Jun 13 '24 16:06 achow101

Thanks for the reviews @josibake, @sipa, @achow101. There's a similar small optimization for transaction input/output allocations as well, I'd appreciate a review.

l0rinc avatar Jun 13 '24 16:06 l0rinc