Reserved memory for the transaction inputs and outputs.
Split out of https://github.com/bitcoin/bitcoin/pull/30050/files#r1597631104
Reserved memory for the transaction inputs and outputs.
Split out of https://github.com/bitcoin/bitcoin/pull/30050/files#r1597631104
<!--e57a25ab6845829454e8d69fc972939a-->
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.
<!--006a51241073e994b41acfe9ec718e94-->
For detailed information about the code coverage, see the test coverage report.
<!--021abf342d371248e50ceaed478a90ca-->
See the guideline for information on the review process.
| Type | Reviewers |
|---|---|
| ACK | TheCharlatan, stickies-v, achow101 |
| Concept ACK | josibake |
| Stale ACK | theuni |
If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.
<!--174a7506f384e20aa4161008e828411d-->
Reviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.
1087 | @@ -1088,6 +1088,7 @@ static util::Result<CreatedTransactionResult> CreateTransactionInternal( 1088 | coin_selection_params.tx_noinputs_size = 10 + GetSizeOfCompactSize(vecSend.size()); // bytes for output count 1089 | 1090 | // vouts to the payees 1091 | + txNew.vout.reserve(txNew.vout.size() + vecSend.size());
A few suggestions:
txNew.vout is always empty here, so I'm not sure why we'd bother to add txNew.vout.size() unless I'm missing something ?vecSend.size()+1 just in case.std::moved (in both places) instead to save a copy similar to #30094?.reserve() for the txNew.vin as well?Hey @theuni, excellent review, thanks!
txNew.vin, I've changed it to emplace_back instead, the performance should be comparable - do you agree?Concept ACK
1098 | @@ -1098,7 +1099,7 @@ static util::Result<CreatedTransactionResult> CreateTransactionInternal( 1099 | if (IsDust(txout, wallet.chain().relayDustFee())) { 1100 | return util::Error{_("Transaction amount too small")}; 1101 | } 1102 | - txNew.vout.push_back(txout); 1103 | + txNew.vout.emplace_back(txout);
This will just be forwarded to the copy ctor. push_back(std::move(txout)) would be more correct (and clear).
I've added benchmarks to verify:
| ns/op | op/s | err% | total | benchmark
|--------------------:|--------------------:|--------:|----------:|:----------
| 2,089.91 | 478,489.15 | 0.1% | 1.10 | `BenchmarkAddOutputsEmplaceBackReserve`
| 1,257.81 | 795,031.71 | 0.1% | 1.10 | `BenchmarkAddOutputsInPlaceEmplaceBackReserve`
| 2,594.12 | 385,487.12 | 0.2% | 1.10 | `BenchmarkAddOutputsPushBack`
| 1,667.85 | 599,573.52 | 0.1% | 1.10 | `BenchmarkAddOutputsPushBackMoveReserve`
| 2,089.21 | 478,649.26 | 0.1% | 1.10 | `BenchmarkAddOutputsPushBackReserve`
ended up adding it directly to txNew.vout which is both faster and simpler - what do you think?
Concept ACK
I noticed you have benchmarks, would be nice to have the comparison of old vs new in the PR description.
Thanks for the review @josibake, I've added the conclusions of the benchmarks to the commit message (but copied it to the PR description as well now), can you please check if https://github.com/bitcoin/bitcoin/pull/30093/commits/ebf8667f634653a2eebe404469bfb62c5bb3add2 answers your questions? @theuni, appreciate your previous reviews and insights, please take a look at the changes I did since.
Changes look good. The bench is not really useful though, because it's testing things that aren't in our code.
I believe @josibake was asking for a bench that demonstrates a before/after of CreateTransactionInternal. I'm guessing that's not really feasible though, so I think it's enough to use your bench numbers without actually committing it.
Moved the benchmark out to https://gist.github.com/paplorinc/812007eef71d5285be0654375ea3e03e
1090 | @@ -1091,15 +1091,14 @@ static util::Result<CreatedTransactionResult> CreateTransactionInternal( 1091 | txNew.vout.reserve(vecSend.size() + 1); // accommodate the possible later inserts 1092 | for (const auto& recipient : vecSend) 1093 | { 1094 | - CTxOut txout(recipient.nAmount, GetScriptForDestination(recipient.dest)); 1095 | + auto& txout = txNew.vout.emplace_back(recipient.nAmount, GetScriptForDestination(recipient.dest));
One last nit: because it's not modified after creation, const auto& txout
Done, thanks
utACK db2a31c339ad697f1828cde162f4df2231c9b0f1
Accommodating possible later insert as well
Co-authored-by: Cory Fields <cory-nospam-@coryfields.com>
Co-authored-by: Cory Fields <cory-nospam-@coryfields.com>
ACK ec585f11c38bbe277a596dcea3c813e7c6626050
ACK ec585f11c38bbe277a596dcea3c813e7c6626050
ACK ec585f11c38bbe277a596dcea3c813e7c6626050