Merge bitcoin/bitcoin#29607: refactor: Reduce memory copying operations in bech32 encoding

07f64177a4 Reduce memory copying operations in bech32 encode (Lőrinc)
d5ece3c4b5 Reserve hrp memory in Decode and LocateErrors (Lőrinc)

Pull request description:

  Started optimizing the base conversions in [TryParseHex](https://github.com/bitcoin/bitcoin/pull/29458), [Base58](https://github.com/bitcoin/bitcoin/pull/29473) and [IsSpace](https://github.com/bitcoin/bitcoin/pull/29602) - this is the next step.

  Part of this change was already merged in https://github.com/bitcoin/bitcoin/pull/30047, which made decoding `~26%` faster.

  Here I've reduced the memory reallocations and copying operations in bech32 encode, making it `~15%` faster.

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

  Before:
  ```
  |             ns/byte |              byte/s |    err% |     total | benchmark
  |--------------------:|--------------------:|--------:|----------:|:----------
  |               19.97 |       50,074,562.72 |    0.1% |      1.06 | `Bech32Encode`
  ```

  After:
  ```
  |             ns/byte |              byte/s |    err% |     total | benchmark
  |--------------------:|--------------------:|--------:|----------:|:----------
  |               17.33 |       57,687,668.20 |    0.1% |      1.10 | `Bech32Encode`
  ```

ACKs for top commit:
  josibake:
    ACK 07f64177a4
  sipa:
    utACK 07f64177a4
  achow101:
    ACK 07f64177a4

Tree-SHA512: 511885217d044ad7ef2bdf9203b8e0b94eec8b279bc193bb7e63e29ab868df6d21e9e4c7a24390358e1f9c131447ee42039df72edcf1e2b11e1856eb2b3e10dd
This commit is contained in:
Ava Chow 2024-06-13 12:18:49 -04:00
commit fcc3b653dc
No known key found for this signature in database
GPG Key ID: 17565732E08E5E41

View File

@ -363,13 +363,13 @@ std::string Encode(Encoding encoding, const std::string& hrp, const data& values
// to return a lowercase Bech32/Bech32m string, but if given an uppercase HRP, the
// result will always be invalid.
for (const char& c : hrp) assert(c < 'A' || c > 'Z');
data checksum = CreateChecksum(encoding, hrp, values);
data combined = Cat(values, checksum);
std::string ret = hrp + '1';
ret.reserve(ret.size() + combined.size());
for (const auto c : combined) {
ret += CHARSET[c];
}
std::string ret;
ret.reserve(hrp.size() + 1 + values.size() + CHECKSUM_SIZE);
ret += hrp;
ret += '1';
for (const uint8_t& i : values) ret += CHARSET[i];
for (const uint8_t& i : CreateChecksum(encoding, hrp, values)) ret += CHARSET[i];
return ret;
}
@ -393,6 +393,7 @@ DecodeResult Decode(const std::string& str, CharLimit limit) {
values[i] = rev;
}
std::string hrp;
hrp.reserve(pos);
for (size_t i = 0; i < pos; ++i) {
hrp += LowerCase(str[i]);
}
@ -425,6 +426,7 @@ std::pair<std::string, std::vector<int>> LocateErrors(const std::string& str, Ch
}
std::string hrp;
hrp.reserve(pos);
for (size_t i = 0; i < pos; ++i) {
hrp += LowerCase(str[i]);
}