Merge bitcoin/bitcoin#29458: refactor: Preallocate result in TryParseHex to avoid resizing

a19235c14b Preallocate result in `TryParseHex` to avoid resizing (Lőrinc)
b7489ecb52 Add benchmark for TryParseHex (Lőrinc)

Pull request description:

  This pull request introduces optimizations to the `TryParseHex` function, focusing primarily on the ideal case (valid hexadecimal input without spaces).
  A new benchmark, `HexParse` was introduced in a separate commit.

  The main optimization preallocates the result vector based on the input string's length. This aims to completely avoid costly dynamic reallocations when no spaces are present.

  ------------

  Before:
  ```
  |           ns/base16 |            base16/s |    err% |     total | benchmark
  |--------------------:|--------------------:|--------:|----------:|:----------
  |                1.60 |      623,238,893.11 |    0.3% |      0.01 | `HexParse`
  |                1.65 |      606,747,566.34 |    0.6% |      0.01 | `HexParse`
  |                1.60 |      626,149,544.07 |    0.3% |      0.01 | `HexParse`
  ```

  After:
  ```
  |           ns/base16 |            base16/s |    err% |     total | benchmark
  |--------------------:|--------------------:|--------:|----------:|:----------
  |                0.68 |    1,465,555,976.27 |    0.8% |      0.01 | `HexParse`
  |                0.68 |    1,472,962,920.18 |    0.3% |      0.01 | `HexParse`
  |                0.68 |    1,476,159,423.00 |    0.3% |      0.01 | `HexParse`
  ```

ACKs for top commit:
  achow101:
    ACK a19235c14b
  hebasto:
    ACK a19235c14b.
  andrewtoth:
    Re-ACK a19235c14b
  Empact:
    Re-ACK a19235c14b

Tree-SHA512: e09a59791104be3fd1026862ce98de9efafa1f949626fa01e3b7d58e6a2ef02a11f0de55ddba5c43230a53effd24e6d368c1e12848b17e8ce91d7908a59333f0
This commit is contained in:
Ava Chow
2024-03-11 09:34:19 -04:00
3 changed files with 39 additions and 0 deletions

View File

@@ -81,6 +81,8 @@ template <typename Byte>
std::optional<std::vector<Byte>> TryParseHex(std::string_view str)
{
std::vector<Byte> vch;
vch.reserve(str.size() / 2); // two hex characters form a single byte
auto it = str.begin();
while (it != str.end()) {
if (IsSpace(*it)) {