hashcodecs 1.4.0__tar.gz → 1.4.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. hashcodecs-1.4.2/BENCHMARK.md +165 -0
  2. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/CHANGELOG.md +35 -1
  3. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/CITATION.cff +2 -2
  4. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/Cargo.lock +1 -1
  5. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/Cargo.toml +1 -1
  6. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/PKG-INFO +14 -13
  7. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/README.md +13 -12
  8. hashcodecs-1.4.2/SAFETY.md +120 -0
  9. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/benches/crossover.rs +9 -5
  10. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/benches/xxhash.rs +7 -1
  11. hashcodecs-1.4.2/docs/ARCHITECTURE.md +267 -0
  12. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/docs/performance.md +13 -6
  13. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/hatch_build.py +1 -1
  14. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/pyproject.toml +10 -10
  15. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/base64/decode/avx2.rs +17 -31
  16. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/base64/decode/sse41.rs +10 -7
  17. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/base64/decode/ssse3.rs +9 -6
  18. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/base64/decode/tables.rs +12 -0
  19. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/base64/tests.rs +93 -10
  20. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/base64.rs +0 -2
  21. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/bindings/arguments.rs +8 -3
  22. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/bindings/base64/api.rs +16 -22
  23. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/bindings/base64/batch.rs +32 -28
  24. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/bindings/base64/configured.rs +70 -9
  25. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/bindings/base64/configured_tests.rs +4 -0
  26. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/bindings/base64/decode.rs +473 -66
  27. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/bindings/base64/encode.rs +101 -66
  28. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/bindings/base64/lenient.rs +88 -15
  29. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/bindings/base64/policy.rs +49 -4
  30. hashcodecs-1.4.2/src/bindings/base64/strict.rs +187 -0
  31. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/bindings/buffer.rs +264 -18
  32. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/bindings/objects.rs +2 -2
  33. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/bindings/schema.rs +41 -10
  34. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/bindings/xxhash/batch.rs +127 -21
  35. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/murmur3/dispatch.rs +4 -2
  36. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/murmur3/tests.rs +74 -21
  37. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/xxhash/long_inputs.rs +1 -1
  38. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/xxhash/one_shot.rs +1 -1
  39. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/xxhash/primitives.rs +2 -2
  40. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/xxhash/short_inputs.rs +34 -21
  41. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/xxhash/tests.rs +25 -0
  42. hashcodecs-1.4.0/BENCHMARK.md +0 -195
  43. hashcodecs-1.4.0/SAFETY.md +0 -47
  44. hashcodecs-1.4.0/docs/ARCHITECTURE.md +0 -218
  45. hashcodecs-1.4.0/src/bindings/base64/strict.rs +0 -274
  46. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/.gitignore +0 -0
  47. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/LICENSE +0 -0
  48. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/LICENSE-MIT +0 -0
  49. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/SECURITY.md +0 -0
  50. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/benches/Cargo.toml +0 -0
  51. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/benches/base64.rs +0 -0
  52. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/benches/murmur3.rs +0 -0
  53. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/benches/support/mod.rs +0 -0
  54. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/build.rs +0 -0
  55. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/docs/api/base64.md +0 -0
  56. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/docs/api/murmur3.md +0 -0
  57. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/docs/api/xxh3.md +0 -0
  58. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/docs/base64.md +0 -0
  59. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/docs/compatibility.md +0 -0
  60. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/docs/index.md +0 -0
  61. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/docs/murmur3.md +0 -0
  62. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/docs/requirements.txt +0 -0
  63. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/docs/xxh3.md +0 -0
  64. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/generated/rust/binding_schema.rs +0 -0
  65. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/generated/rust/murmur3_classes.rs +0 -0
  66. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/hashcodecs/__init__.py +0 -0
  67. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/hashcodecs/__init__.pyi +0 -0
  68. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/hashcodecs/_hashcodecs.pyi +0 -0
  69. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/hashcodecs/base64.py +0 -0
  70. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/hashcodecs/base64.pyi +0 -0
  71. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/hashcodecs/murmur3.py +0 -0
  72. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/hashcodecs/murmur3.pyi +0 -0
  73. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/hashcodecs/py.typed +0 -0
  74. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/hashcodecs/xxhash.py +0 -0
  75. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/hashcodecs/xxhash.pyi +0 -0
  76. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/backend.rs +0 -0
  77. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/base64/alphabet.rs +0 -0
  78. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/base64/backend.rs +0 -0
  79. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/base64/decode/aarch64.rs +0 -0
  80. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/base64/decode/avx512.rs +0 -0
  81. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/base64/decode/x86_contracts.rs +0 -0
  82. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/base64/decode.rs +0 -0
  83. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/base64/encode/aarch64.rs +0 -0
  84. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/base64/encode/avx2.rs +0 -0
  85. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/base64/encode/avx512.rs +0 -0
  86. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/base64/encode/cache.rs +0 -0
  87. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/base64/encode/ssse3.rs +0 -0
  88. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/base64/encode.rs +0 -0
  89. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/base64/error.rs +0 -0
  90. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/base64/miri_tests.rs +0 -0
  91. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/base64/output_buffer.rs +0 -0
  92. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/base64/proofs.rs +0 -0
  93. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/base64/runtime_dispatch.rs +0 -0
  94. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/base64/tests/aarch64.rs +0 -0
  95. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/bindings/base64/scan/aarch64.rs +0 -0
  96. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/bindings/base64/scan/scalar.rs +0 -0
  97. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/bindings/base64/scan/x86.rs +0 -0
  98. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/bindings/base64/scan.rs +0 -0
  99. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/bindings/base64/staging.rs +0 -0
  100. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/bindings/base64.rs +0 -0
  101. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/bindings/compatibility.rs +0 -0
  102. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/bindings/murmur3/callbacks.rs +0 -0
  103. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/bindings/murmur3/digest.rs +0 -0
  104. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/bindings/murmur3/incremental.rs +0 -0
  105. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/bindings/murmur3/methods.rs +0 -0
  106. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/bindings/murmur3.rs +0 -0
  107. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/bindings/runtime.rs +0 -0
  108. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/bindings/xxhash/callbacks.rs +0 -0
  109. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/bindings/xxhash/methods.rs +0 -0
  110. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/bindings/xxhash.rs +0 -0
  111. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/bindings.rs +0 -0
  112. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/lib.rs +0 -0
  113. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/murmur3/block_buffer.rs +0 -0
  114. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/murmur3/miri_tests.rs +0 -0
  115. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/murmur3/primitives.rs +0 -0
  116. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/murmur3/proofs.rs +0 -0
  117. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/murmur3/x64_128/x86.rs +0 -0
  118. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/murmur3/x64_128.rs +0 -0
  119. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/murmur3/x86_128/x86.rs +0 -0
  120. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/murmur3/x86_128.rs +0 -0
  121. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/murmur3/x86_32/x86.rs +0 -0
  122. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/murmur3/x86_32.rs +0 -0
  123. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/murmur3.rs +0 -0
  124. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/xxhash/batch.rs +0 -0
  125. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/xxhash/long_inputs/aarch64.rs +0 -0
  126. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/xxhash/long_inputs/scalar.rs +0 -0
  127. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/xxhash/long_inputs/x86/avx2.rs +0 -0
  128. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/xxhash/long_inputs/x86/avx2_batch.rs +0 -0
  129. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/xxhash/long_inputs/x86/avx512.rs +0 -0
  130. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/xxhash/long_inputs/x86/ssse3.rs +0 -0
  131. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/xxhash/long_inputs/x86.rs +0 -0
  132. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/xxhash/miri_tests.rs +0 -0
  133. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/xxhash/prepared.rs +0 -0
  134. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/xxhash/proofs.rs +0 -0
  135. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/src/xxhash.rs +0 -0
  136. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/tools/generate_api_metadata.py +0 -0
  137. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/tools/install_local_wheel.py +0 -0
  138. {hashcodecs-1.4.0 → hashcodecs-1.4.2}/tools/verify_sdist.py +0 -0
@@ -0,0 +1,165 @@
1
+ # Benchmarks
2
+
3
+ Use this reference to compare `hashcodecs` APIs and reproduce the measurements for a change. For the implementation
4
+ behind the results, read [Architecture](docs/ARCHITECTURE.md).
5
+
6
+ ## Measurement conditions
7
+
8
+ | Setting | Recorded comparison |
9
+ | --- | --- |
10
+ | Host | Windows 10 x64, Intel Core Ultra 7 265K |
11
+ | Execution | One thread, pinned to one logical CPU |
12
+ | Rust | Criterion, 50 samples per case, release optimization |
13
+ | Python timing | Median of 15 samples, calibrated to at least 0.2 seconds per sample |
14
+ | Python | Free-threaded CPython 3.14.6 (`3.14t`), GIL disabled |
15
+ | Python baselines | pybase64 1.5.0, mmh3 5.3.0, xxhash 4.0.1 |
16
+ | Allocation | `mimalloc` for Rust benchmark allocations and Rust allocations in the Python extension |
17
+ | XXH3 C baseline | xxHash 0.8.3 through `xxhash-c-sys`, compiled with AVX2 to match this host's selected backend |
18
+
19
+ Charts report GiB/s (2³⁰ bytes per second). Higher values mean greater throughput. Base64 uses the original binary
20
+ payload size for both encoding and decoding. Batch throughput counts the total payload across items. Default
21
+ Python Base64 comparisons use immutable `bytes` and strict decoding (`validate=True`).
22
+
23
+ Cases that return output include result allocation. Cases with reusable output allocate destinations before timing.
24
+ The harnesses reuse inputs across iterations, so cache residency affects the results. Compare like input types,
25
+ sizes, and output models. These measurements describe this host and workload.
26
+
27
+ The repository's [results.csv](docs/benchmarks/results.csv) supplies the chart values. Focused updates replace the
28
+ affected series and retain the other measurements, so the charts combine results from multiple runs.
29
+
30
+ ## Base64 results
31
+
32
+ | API and workload | Charts |
33
+ | --- | --- |
34
+ | Rust, standard Base64 and Base64 for URLs | [Rust Base64](docs/benchmarks/base64-rust.svg) |
35
+ | Python, standard Base64 and Base64 for URLs | [Python Base64](docs/benchmarks/base64-python.svg) |
36
+ | Python, reusable `bytearray` output | [Reusable buffers](docs/benchmarks/base64-python-reusable.svg) |
37
+ | Python, MIME whitespace and ignored characters outside the alphabet | [Lenient decoding](docs/benchmarks/base64-python-lenient.svg) |
38
+ | Python, full and sliced immutable views | [Memoryview inputs](docs/benchmarks/base64-python-memoryview.svg) |
39
+ | Python, ASCII `str` decoding | [String inputs](docs/benchmarks/base64-python-str.svg) |
40
+ | Python, mutable `bytearray` input | [Mutable inputs](docs/benchmarks/base64-python-mutable.svg) |
41
+ | Python, batches | [Returned bytes](docs/benchmarks/base64-python-batch.svg), [reusable outputs](docs/benchmarks/base64-python-batch-reusable.svg) |
42
+ | Python, batches of memoryviews | [Memoryview batches](docs/benchmarks/base64-python-batch-memoryview.svg) |
43
+ | Python, batches of 1 MiB items | [Large batches](docs/benchmarks/base64-python-batch-large.svg) |
44
+
45
+ Batch charts use item count on the horizontal axis. Reusable Base64 batches provide one destination per item.
46
+ Lenient cases insert CRLF or `!` after each line of 76 characters.
47
+
48
+ ## MurmurHash3 results
49
+
50
+ | API and workload | Charts |
51
+ | --- | --- |
52
+ | Rust, x86-32, x86-128, and x64-128 | [Rust MurmurHash3](docs/benchmarks/murmur3-rust.svg) |
53
+ | Python, single calls and incremental hashing | [Python MurmurHash3](docs/benchmarks/murmur3-python.svg) |
54
+ | Python, mutable `bytearray` input | [Mutable inputs](docs/benchmarks/murmur3-python-mutable.svg) |
55
+
56
+ Incremental cases include construction, `update`, and digest creation.
57
+
58
+ ## XXH3 results
59
+
60
+ | API and workload | Charts |
61
+ | --- | --- |
62
+ | Rust, XXH3-64 and XXH3-128, single calls and batches of 32 items | [Rust XXH3](docs/benchmarks/xxh3-rust.svg) |
63
+ | Rust, batches of two and three items | [Batch remainders](docs/benchmarks/xxh3-rust-batch-remainders.svg) |
64
+ | Python, single calls, list results, and packed output | [Python XXH3](docs/benchmarks/xxh3-python.svg) |
65
+
66
+ Rust allocating batches include allocation of the result vector. Python list batches create one integer per digest.
67
+ Packed batches write digests in little endian order into one reusable `bytearray`. Python batch comparisons use
68
+ 32 inputs of equal size by default and compare against the upstream `xxhash` extension.
69
+
70
+ The Python small-input panels cover 16, 17, 33, 65, 97, and 240 bytes. These sizes use scalar formulas; runtime SIMD
71
+ dispatch starts at 241 bytes.
72
+
73
+ ## Reproduce a benchmark
74
+
75
+ Run commands from the repository root. Install Rust 1.89 or newer, a C/C++ compiler and linker for your platform,
76
+ and `uv`. Use free-threaded CPython 3.14 for the Python charts. The Python setup below builds and installs the
77
+ current checkout as a CPython wheel through Hatchling.
78
+
79
+ Run the group affected by your change. Reserve a complete run for changes that can affect all groups. Keep
80
+ benchmarks out of CI. The standard harnesses set CPU affinity on Windows and Linux. On other platforms, arrange
81
+ equivalent CPU pinning before collecting comparison results.
82
+
83
+ ### Rust
84
+
85
+ Choose the relevant harness:
86
+
87
+ ```sh
88
+ cargo bench --manifest-path benches/Cargo.toml --bench base64
89
+ cargo bench --manifest-path benches/Cargo.toml --bench murmur3
90
+ cargo bench --manifest-path benches/Cargo.toml --bench xxhash
91
+ ```
92
+
93
+ To reproduce the Windows XXH3 C baseline, set the compiler flags and rebuild its package before running the harness:
94
+
95
+ ```powershell
96
+ $env:CFLAGS = '/O2 /arch:AVX2'
97
+ cargo clean -p xxhash-c-sys
98
+ cargo bench --manifest-path benches/Cargo.toml --bench xxhash
99
+ ```
100
+
101
+ Use the equivalent AVX2 compiler flag on other platforms. Match the baseline instruction set to the backend under
102
+ comparison. Pass a Criterion name filter after `--` to narrow a run:
103
+
104
+ ```sh
105
+ cargo bench --manifest-path benches/Cargo.toml --bench murmur3 -- x64_128/hashcodecs
106
+ ```
107
+
108
+ ### Python
109
+
110
+ Prepare the free-threaded interpreter (`3.14t`) and pinned benchmark dependencies. Repeat the wheel installation
111
+ after changing native code or switching interpreters:
112
+
113
+ ```sh
114
+ uv sync --python 3.14t --frozen --group benchmark --no-install-project
115
+ uv run --python 3.14t --frozen --no-sync python tools/install_local_wheel.py
116
+ ```
117
+
118
+ Choose the relevant script:
119
+
120
+ ```sh
121
+ uv run --python 3.14t --frozen --no-sync python benchmarks/python_base64.py
122
+ uv run --python 3.14t --frozen --no-sync python benchmarks/python_base64_batch.py
123
+ uv run --python 3.14t --frozen --no-sync python benchmarks/python_murmur3.py
124
+ uv run --python 3.14t --frozen --no-sync python benchmarks/python_xxhash.py
125
+ ```
126
+
127
+ The scripts check outputs before timing and print GiB/s. Append a mode from the table to select a workload. Use
128
+ `--help` for the full option list.
129
+
130
+ | Script | Focused modes |
131
+ | --- | --- |
132
+ | `python_base64.py` | `--into`, `--lenient`, `--custom-lenient`, `--bytearray-input`, `--memoryview-input`, `--sliced-memoryview-input`, `--str-input` |
133
+ | `python_base64_batch.py` | `--large`, `--memoryview-input`, `--decode-only`. Select sizes with `--item-sizes` and `--batch-sizes`. |
134
+ | `python_murmur3.py` | `--incremental`, `--bytearray-input` |
135
+ | `python_xxhash.py` | `--one-shot-only`, `--sizes 17 33 65 97 240`, `--batches-only`, `--batch-counts 2 3` |
136
+
137
+ `python_base64.py` accepts one mode per run. Its `--configured` and `--wrapped` modes require CPython 3.15 or newer.
138
+ Use that interpreter for both setup commands and the benchmark. These modes cover configured decoding and
139
+ encoding with newlines after 76 output characters.
140
+
141
+ The four scripts accept `--hashcodecs-only` to skip competitor timing. The Base64 script treats that flag as a
142
+ mode, so run it apart from `--into`, `--lenient`, and the other Base64 modes. All four accept `--samples` and
143
+ `--minimum-sample-seconds`. Keep the defaults for published comparisons. Lower them for local exploration.
144
+
145
+ For call overhead, run `benchmarks/python_calls.py` with the same `uv run` prefix. It reports nanoseconds per call
146
+ and supports `--keywords`, `--thresholds`, and `--buffer-inputs`. Its `--thread-scaling` mode measures aggregate
147
+ throughput without pinning to one CPU. Keep those results separate from the charts above.
148
+
149
+ ## Update the charts
150
+
151
+ 1. Copy the measured GiB/s values into [results.csv](docs/benchmarks/results.csv). Update the series you measured.
152
+ Retain unmeasured values and leave `gib_per_second` empty for unavailable results.
153
+ 2. Keep matching input categories across implementations in each panel. Each row identifies a chart, panel,
154
+ input category, and implementation. Row order controls chart, panel, category, and legend order.
155
+ 3. Render the SVG files:
156
+
157
+ ```sh
158
+ uv run --python 3.14t --no-project python benchmarks/render_charts.py
159
+ ```
160
+
161
+ 4. Review the CSV and SVG diff. A focused update should change the corresponding charts, including any README
162
+ overview that uses those values.
163
+
164
+ The renderer reads the CSV without running benchmarks or changing measurements. Keep temporary tuning sweeps,
165
+ branch comparisons, and profiler output out of this reference.
@@ -4,6 +4,38 @@ This file records notable user-facing changes to `hashcodecs`. Version 1.0.0 sta
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [1.4.2] - 2026-09-29
8
+
9
+ ### What's Changed
10
+ * perf: Improve AVX2 Base64 decoding throughput by @kozistr in https://github.com/kozistr/hashcodecs-rs/pull/125
11
+ * perf: Reduce SSE Base64 decode stores by @kozistr in https://github.com/kozistr/hashcodecs-rs/pull/126
12
+ * perf: Reduce Python Base64 ASCII decoding overhead by @kozistr in https://github.com/kozistr/hashcodecs-rs/pull/127
13
+ * docs: Clarify benchmarks, architecture, and safety guidance by @kozistr in https://github.com/kozistr/hashcodecs-rs/pull/128
14
+ * chore: Refresh all Python benchmarks on free-threaded 3.14 by @kozistr in https://github.com/kozistr/hashcodecs-rs/pull/129
15
+ * perf: Reduce Python XXH3 seed conversion overhead by @kozistr in https://github.com/kozistr/hashcodecs-rs/pull/130
16
+ * perf: Speed up short XXH3 inputs by @kozistr in https://github.com/kozistr/hashcodecs-rs/pull/131
17
+
18
+
19
+ **Full Changelog**: https://github.com/kozistr/hashcodecs-rs/compare/v1.4.1...v1.4.2
20
+
21
+ ## [1.4.1] - 2026-09-13
22
+
23
+ ### What's Changed
24
+ * fix: match CPython Base64 and XXH3 buffer semantics by @kozistr in https://github.com/kozistr/hashcodecs-rs/pull/114
25
+ * fix: preserve Base64 callback buffer semantics by @kozistr in https://github.com/kozistr/hashcodecs-rs/pull/115
26
+ * fix: preserve CPython Base64 observable behavior by @kozistr in https://github.com/kozistr/hashcodecs-rs/pull/116
27
+ * fix: resolve repository type diagnostics by @kozistr in https://github.com/kozistr/hashcodecs-rs/pull/117
28
+ * fix: release Base64 input buffers before writing output by @kozistr in https://github.com/kozistr/hashcodecs-rs/pull/118
29
+ * refactor: centralize buffer callback policy and clarify finalizers by @kozistr in https://github.com/kozistr/hashcodecs-rs/pull/119
30
+ * fix: accelerate custom-alphabet lenient Base64 decoding by @kozistr in https://github.com/kozistr/hashcodecs-rs/pull/120
31
+ * fix: reduce XXH3 packed batch detachment overhead by @kozistr in https://github.com/kozistr/hashcodecs-rs/pull/121
32
+ * fix: delay MurmurHash3 x64 SIMD dispatch until 512 bytes by @kozistr in https://github.com/kozistr/hashcodecs-rs/pull/122
33
+ * fix: restore Python buffer and batch throughput by @kozistr in https://github.com/kozistr/hashcodecs-rs/pull/123
34
+ * fix: typo in the performance viz image by @kozistr in https://github.com/kozistr/hashcodecs-rs/pull/124
35
+
36
+
37
+ **Full Changelog**: https://github.com/kozistr/hashcodecs-rs/compare/v1.4.0...v1.4.1
38
+
7
39
  ## [1.4.0] - 2026-09-10
8
40
 
9
41
  ### What's Changed
@@ -193,7 +225,9 @@ This file records notable user-facing changes to `hashcodecs`. Version 1.0.0 sta
193
225
  - Initial Python and Rust APIs for Base64 and MurmurHash3.
194
226
  - Runtime SIMD dispatch and platform-specific CPython wheels.
195
227
 
196
- [Unreleased]: https://github.com/kozistr/hashcodecs-rs/compare/v1.4.0...HEAD
228
+ [Unreleased]: https://github.com/kozistr/hashcodecs-rs/compare/v1.4.2...HEAD
229
+ [1.4.2]: https://github.com/kozistr/hashcodecs-rs/compare/v1.4.1...v1.4.2
230
+ [1.4.1]: https://github.com/kozistr/hashcodecs-rs/compare/v1.4.0...v1.4.1
197
231
  [1.4.0]: https://github.com/kozistr/hashcodecs-rs/compare/v1.3.0...v1.4.0
198
232
  [1.3.0]: https://github.com/kozistr/hashcodecs-rs/compare/v1.2.1...v1.3.0
199
233
  [1.2.1]: https://github.com/kozistr/hashcodecs-rs/compare/v1.2.0...v1.2.1
@@ -5,8 +5,8 @@ authors:
5
5
  given-names: Hyeongchan
6
6
  orcid: https://orcid.org/0000-0002-1729-0580
7
7
  title: "hashcodecs: SIMD-accelerated Base64, MurmurHash3, and XXH3 for Python and Rust"
8
- version: 1.4.0
9
- date-released: 2026-09-10
8
+ version: 1.4.2
9
+ date-released: 2026-09-29
10
10
  license: "MIT OR Apache-2.0"
11
11
  repository-code: "https://github.com/kozistr/hashcodecs-rs"
12
12
  url: "https://github.com/kozistr/hashcodecs-rs"
@@ -194,7 +194,7 @@ dependencies = [
194
194
 
195
195
  [[package]]
196
196
  name = "hashcodecs"
197
- version = "1.4.0"
197
+ version = "1.4.2"
198
198
  dependencies = [
199
199
  "base64",
200
200
  "memchr",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "hashcodecs"
3
- version = "1.4.0"
3
+ version = "1.4.2"
4
4
  edition = "2024"
5
5
  rust-version = "1.89"
6
6
  autobenches = false
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: hashcodecs
3
- Version: 1.4.0
3
+ Version: 1.4.2
4
4
  Summary: SIMD-accelerated Base64, MurmurHash3, and xxHash codecs
5
5
  Project-URL: Documentation, https://hashcodecs-rs.readthedocs.io/
6
6
  Project-URL: Repository, https://github.com/kozistr/hashcodecs-rs
@@ -43,7 +43,7 @@ Description-Content-Type: text/markdown
43
43
 
44
44
  <p align="center">
45
45
  <a href="BENCHMARK.md">
46
- <img src="docs/benchmarks/performance-at-a-glance.svg" alt="CPython 3.12 standard Base64 encoding and decoding benchmark">
46
+ <img src="docs/benchmarks/performance-at-a-glance.svg" alt="Free-threaded CPython 3.14.6 standard Base64 encoding and decoding benchmark">
47
47
  </a>
48
48
  </p>
49
49
 
@@ -184,6 +184,7 @@ CPython boundary, and safety invariants.
184
184
 
185
185
  Run the suite on Windows 10 x64 with an Intel Core Ultra 7 265K. Pin one logical CPU and run each case in one thread.
186
186
  Collect 50 Rust samples and 15 Python samples. Higher throughput wins.
187
+ Use free-threaded CPython 3.14.6 with the GIL disabled for all Python charts.
187
188
 
188
189
  ### Base64: Rust
189
190
 
@@ -230,12 +231,13 @@ cargo bench --manifest-path benches/Cargo.toml --bench murmur3
230
231
  cargo bench --manifest-path benches/Cargo.toml --bench xxhash
231
232
  cargo bench --manifest-path benches/Cargo.toml --bench crossover
232
233
 
233
- uv sync --group benchmark --no-install-project
234
- uv run --no-project --with . python benchmarks/python_base64.py
235
- uv run --no-project --with . python benchmarks/python_base64_batch.py
236
- uv run --no-project --with . python benchmarks/python_calls.py
237
- uv run --no-project --with . python benchmarks/python_murmur3.py
238
- uv run --no-project --with . python benchmarks/python_xxhash.py
234
+ uv sync --python 3.14t --frozen --group benchmark --no-install-project
235
+ uv run --python 3.14t --frozen --no-sync python tools/install_local_wheel.py
236
+ uv run --python 3.14t --frozen --no-sync python benchmarks/python_base64.py
237
+ uv run --python 3.14t --frozen --no-sync python benchmarks/python_base64_batch.py
238
+ uv run --python 3.14t --frozen --no-sync python benchmarks/python_calls.py
239
+ uv run --python 3.14t --frozen --no-sync python benchmarks/python_murmur3.py
240
+ uv run --python 3.14t --frozen --no-sync python benchmarks/python_xxhash.py
239
241
  ```
240
242
 
241
243
  The Python benchmarks expose focused modes such as `--into`, `--lenient`, `--bytearray-input`, `--memoryview-input`,
@@ -253,11 +255,10 @@ cargo bench --manifest-path benches/Cargo.toml --bench xxhash
253
255
 
254
256
  ## Performance snapshot
255
257
 
256
- In the focused 2026-09-09 hashcodecs-only run on the benchmark host, `hashcodecs.xxh3_64` processes a 1 MiB input
257
- at 91.27 GiB/s. In the full 2026-09-02 run, the Base64 batch API reaches 11.84 GiB/s for encode and 6.23 GiB/s for
258
- decode with 256 B items in batches of 64. Each run pins one logical CPU and uses 15 samples with a 0.2-second
259
- minimum per sample. Read the
260
- [benchmark details](BENCHMARK.md) and [raw comparison results](docs/benchmarks/results.csv).
258
+ On the benchmark host with CPython 3.14.6t, `hashcodecs.xxh3_64` processes a 1 MiB input at 80.87 GiB/s. The Base64
259
+ batch API reaches 5.10 GiB/s for encode and 5.03 GiB/s for decode with 256 B items in batches of 64. Each run pins
260
+ one logical CPU and uses 15 samples with a 0.2-second minimum per sample. Read the [benchmark details](BENCHMARK.md)
261
+ and [raw comparison results](docs/benchmarks/results.csv).
261
262
 
262
263
  ## Development
263
264
 
@@ -12,7 +12,7 @@
12
12
 
13
13
  <p align="center">
14
14
  <a href="BENCHMARK.md">
15
- <img src="docs/benchmarks/performance-at-a-glance.svg" alt="CPython 3.12 standard Base64 encoding and decoding benchmark">
15
+ <img src="docs/benchmarks/performance-at-a-glance.svg" alt="Free-threaded CPython 3.14.6 standard Base64 encoding and decoding benchmark">
16
16
  </a>
17
17
  </p>
18
18
 
@@ -153,6 +153,7 @@ CPython boundary, and safety invariants.
153
153
 
154
154
  Run the suite on Windows 10 x64 with an Intel Core Ultra 7 265K. Pin one logical CPU and run each case in one thread.
155
155
  Collect 50 Rust samples and 15 Python samples. Higher throughput wins.
156
+ Use free-threaded CPython 3.14.6 with the GIL disabled for all Python charts.
156
157
 
157
158
  ### Base64: Rust
158
159
 
@@ -199,12 +200,13 @@ cargo bench --manifest-path benches/Cargo.toml --bench murmur3
199
200
  cargo bench --manifest-path benches/Cargo.toml --bench xxhash
200
201
  cargo bench --manifest-path benches/Cargo.toml --bench crossover
201
202
 
202
- uv sync --group benchmark --no-install-project
203
- uv run --no-project --with . python benchmarks/python_base64.py
204
- uv run --no-project --with . python benchmarks/python_base64_batch.py
205
- uv run --no-project --with . python benchmarks/python_calls.py
206
- uv run --no-project --with . python benchmarks/python_murmur3.py
207
- uv run --no-project --with . python benchmarks/python_xxhash.py
203
+ uv sync --python 3.14t --frozen --group benchmark --no-install-project
204
+ uv run --python 3.14t --frozen --no-sync python tools/install_local_wheel.py
205
+ uv run --python 3.14t --frozen --no-sync python benchmarks/python_base64.py
206
+ uv run --python 3.14t --frozen --no-sync python benchmarks/python_base64_batch.py
207
+ uv run --python 3.14t --frozen --no-sync python benchmarks/python_calls.py
208
+ uv run --python 3.14t --frozen --no-sync python benchmarks/python_murmur3.py
209
+ uv run --python 3.14t --frozen --no-sync python benchmarks/python_xxhash.py
208
210
  ```
209
211
 
210
212
  The Python benchmarks expose focused modes such as `--into`, `--lenient`, `--bytearray-input`, `--memoryview-input`,
@@ -222,11 +224,10 @@ cargo bench --manifest-path benches/Cargo.toml --bench xxhash
222
224
 
223
225
  ## Performance snapshot
224
226
 
225
- In the focused 2026-09-09 hashcodecs-only run on the benchmark host, `hashcodecs.xxh3_64` processes a 1 MiB input
226
- at 91.27 GiB/s. In the full 2026-09-02 run, the Base64 batch API reaches 11.84 GiB/s for encode and 6.23 GiB/s for
227
- decode with 256 B items in batches of 64. Each run pins one logical CPU and uses 15 samples with a 0.2-second
228
- minimum per sample. Read the
229
- [benchmark details](BENCHMARK.md) and [raw comparison results](docs/benchmarks/results.csv).
227
+ On the benchmark host with CPython 3.14.6t, `hashcodecs.xxh3_64` processes a 1 MiB input at 80.87 GiB/s. The Base64
228
+ batch API reaches 5.10 GiB/s for encode and 5.03 GiB/s for decode with 256 B items in batches of 64. Each run pins
229
+ one logical CPU and uses 15 samples with a 0.2-second minimum per sample. Read the [benchmark details](BENCHMARK.md)
230
+ and [raw comparison results](docs/benchmarks/results.csv).
230
231
 
231
232
  ## Development
232
233
 
@@ -0,0 +1,120 @@
1
+ # Memory safety verification
2
+
3
+ Use this reference when reviewing changes to unsafe Rust or CPython buffer handling. It identifies the memory
4
+ contracts, the checks that exercise them, and the commands to reproduce those checks. For performance mechanisms,
5
+ see [Architecture](docs/ARCHITECTURE.md).
6
+
7
+ ## Required invariants
8
+
9
+ | Boundary | Required contract | Source |
10
+ | --- | --- | --- |
11
+ | CPU dispatch | Check the features required by a kernel and its fallback paths before executing SIMD instructions. | [CPU detection](src/backend.rs), [Base64 dispatch](src/base64/backend.rs), [MurmurHash3 dispatch](src/murmur3/dispatch.rs), [XXH3 engine](src/xxhash/long_inputs.rs) |
12
+ | Input loads | Keep scalar word loads, vector loads, and final overlapping stripes within the input allocation. | [MurmurHash3 loads](src/murmur3/primitives.rs), [XXH3 loads](src/xxhash/primitives.rs), [XXH3 schedule](src/xxhash/long_inputs.rs) |
13
+ | Output stores | Check capacity before writing. Overlapping vector stores need space for their full width. Exact outputs must preserve bytes beyond the returned length. | [Base64 store policies](src/base64/decode/x86_contracts.rs), [output initialization](src/base64/output_buffer.rs) |
14
+ | Result initialization | Initialize the returned prefix before exposing uninitialized storage as a result. | [Base64 allocation](src/base64/output_buffer.rs), [XXH3 batch results](src/bindings/xxhash/batch.rs) |
15
+ | Python ownership | Keep owners alive and stabilize inputs before callbacks, overlapping writes, or interpreter detachment can invalidate a borrow. | [Buffer policy](src/bindings/buffer.rs), [Base64 batches](src/bindings/base64/batch.rs) |
16
+
17
+ Exact output bounds do not imply rollback on errors. Reusable Base64 batches retain prior destination writes.
18
+ Packed XXH3 batches validate and stabilize inputs before mutating the destination.
19
+
20
+ ## CPython ownership and callbacks
21
+
22
+ The global interpreter lock (GIL) does not prevent callbacks from running on the same thread. Python allocation
23
+ can trigger garbage collection and finalizers that clear an input list or resize a `bytearray`. Argument
24
+ conversion and buffer release can also invoke user code. Bindings must preserve input ownership across these
25
+ operations and copy mutable or overlapping data where the buffer policy requires it.
26
+
27
+ XXH3 list batches finish input reads before allocating Python result containers. They store up to 32 native
28
+ results on the stack and use a vector with fallible allocation for larger batches. Base64 batches retain input
29
+ owners across result allocation. Subprocess tests on CPython 3.10 and 3.11 trigger finalizers during allocation
30
+ and reuse freed storage to check these lifetime rules.
31
+
32
+ Detached packed XXH3 batches retain immutable owners and stage digests in native memory. The path for exact
33
+ `bytes` borrows 64 retained inputs at a time in a stack array. After reattaching, the binding rechecks destination
34
+ capacity under synchronization before writing. The private `PackedDigest` contract requires initialized bytes
35
+ without padding and a representation matching the packed output on hosts that use little endian order. Those
36
+ hosts can copy the staged results in one operation. Other hosts serialize each word.
37
+
38
+ Tests cover source list mutation, output resizing, overlapping buffers, and access to mutable data on CPython
39
+ builds without the GIL. See the [XXH3 binding tests](src/bindings/xxhash/batch.rs),
40
+ [XXH3 Python tests](tests/test_xxhash.py), [Base64 batch tests](tests/test_base64_batch.py), and
41
+ [buffer tests](tests/test_base64_buffers.py).
42
+
43
+ ## Verification scope
44
+
45
+ | Check | What it verifies | Limits |
46
+ | --- | --- | --- |
47
+ | Kani | Base64 scalar output bounds, MurmurHash3 and XXH3 word loads, MurmurHash3 scalar block loops, and XXH3 scheduling bounds. | Proofs apply within each harness's assumptions and unwind limits. The XXH3 schedule proof covers 241 through 3,072 bytes. |
48
+ | Miri | Scalar allocation, pointer provenance, exact Base64 outputs, MurmurHash3 incremental state, and XXH3 length classes and batches. | The Miri configuration uses scalar dispatch and does not execute hardware intrinsics. |
49
+ | AddressSanitizer | Invalid memory access in the sanitizer executable, including runtime SIMD paths, exact Base64 outputs, and hash batches. | Exercises inputs in the harness and backends available on the host. |
50
+ | MemorySanitizer | Reads of uninitialized memory in the same executable. | Exercises the instrumented Rust core, including a rebuilt standard library. |
51
+ | libFuzzer | Differential output checks against `base64`, `murmur3`, and `xxhash-rust` under sanitizers. | A timed run samples inputs. XXH3 batches cover one through nine independent buffers with equal or mixed lengths. |
52
+ | Python and Rust binding tests | Callback order, retained owners, alias snapshots, output publication, and thread coordination. | Some cases require a specific CPython version or a build without the GIL. |
53
+
54
+ The Rust Kani, Miri, sanitizer, and fuzz jobs exclude the optional CPython bindings. Binding tests cover that
55
+ boundary. Passing a check establishes its stated coverage, not a proof of all unsafe code.
56
+
57
+ Proof harnesses live in [Base64](src/base64/proofs.rs), [MurmurHash3](src/murmur3/proofs.rs), and
58
+ [XXH3](src/xxhash/proofs.rs). Miri cases live in the corresponding `miri_tests.rs` files.
59
+ The [sanitizer executable](tests/sanitizers.rs), [fuzz targets](fuzz/fuzz_targets), and
60
+ [CI workflow](.github/workflows/ci.yml) define the executed checks.
61
+ [Fuzz dependencies](fuzz/Cargo.toml) record the reference implementations.
62
+
63
+ ## Run the Rust checks on Linux
64
+
65
+ Run these commands from the repository root on Linux x86_64 with a C/C++ compiler and linker installed.
66
+ Install nightly Rust with the `rust-src` and `miri` components, plus `cargo-fuzz`. Install
67
+ [Kani](https://model-checking.github.io/kani/install-guide.html) and complete `cargo kani setup` before running proofs.
68
+
69
+ ```sh
70
+ rustup toolchain install nightly --component rust-src --component miri
71
+ cargo install cargo-fuzz --locked
72
+ ```
73
+
74
+ Run the proofs and scalar interpreter checks:
75
+
76
+ ```sh
77
+ cargo kani
78
+ MIRIFLAGS=-Zmiri-strict-provenance \
79
+ cargo +nightly miri test --lib miri_tests
80
+ ```
81
+
82
+ Run the sanitizer executable with each instrumentation mode:
83
+
84
+ ```sh
85
+ RUSTFLAGS="-Zsanitizer=address" \
86
+ RUSTDOCFLAGS="-Zsanitizer=address" \
87
+ cargo +nightly test -Zbuild-std --target x86_64-unknown-linux-gnu \
88
+ --test sanitizers
89
+
90
+ RUSTFLAGS="-Zsanitizer=memory -Zsanitizer-memory-track-origins" \
91
+ RUSTDOCFLAGS="-Zsanitizer=memory -Zsanitizer-memory-track-origins" \
92
+ cargo +nightly test -Zbuild-std --target x86_64-unknown-linux-gnu \
93
+ --test sanitizers
94
+ ```
95
+
96
+ Run the bounded fuzz checks used in CI:
97
+
98
+ ```sh
99
+ cargo +nightly fuzz run base64 -- -max_total_time=30 -rss_limit_mb=2048
100
+ cargo +nightly fuzz run murmur3 -- -max_total_time=30 -rss_limit_mb=2048
101
+ cargo +nightly fuzz run xxhash -- -max_total_time=30 -rss_limit_mb=2048
102
+ ```
103
+
104
+ Successful runs exit with status zero and no failed proof, assertion, or sanitizer diagnostic. Preserve any
105
+ failing input or counterexample and reproduce the failure before changing the affected code.
106
+
107
+ ## Run the CPython checks
108
+
109
+ Build the current wheel before testing the installed package:
110
+
111
+ ```sh
112
+ uv sync --python 3.12 --frozen --no-install-project
113
+ uv run --python 3.12 --frozen --no-sync python tools/install_local_wheel.py
114
+ uv run --python 3.12 --frozen --no-sync pytest tests
115
+ uv run --python 3.12 --frozen --no-sync cargo test --features python
116
+ ```
117
+
118
+ Repeat the setup and test commands with `3.10` or `3.11` for the finalizer subprocess cases and with `3.15t` for
119
+ cases that require CPython without the GIL. Those tests skip on incompatible interpreters. Check the selected
120
+ interpreter and skipped cases before treating a run as coverage of those behaviors.
@@ -8,6 +8,7 @@ mod support;
8
8
  const BASE64_ENCODE_SIZES: [usize; 10] = [15, 16, 31, 32, 47, 48, 51, 52, 103, 104];
9
9
  const BASE64_DECODE_SIZES: [usize; 8] = [12, 16, 28, 32, 60, 64, 124, 128];
10
10
  const MURMUR_SIZES: [usize; 6] = [15, 16, 31, 32, 255, 256];
11
+ const MURMUR_X64_SIZES: [usize; 12] = [15, 16, 31, 32, 64, 255, 256, 384, 511, 512, 513, 1024];
11
12
 
12
13
  fn data(size: usize) -> Vec<u8> {
13
14
  (0..size)
@@ -41,9 +42,9 @@ fn base64_decode(c: &mut Criterion) {
41
42
  }
42
43
 
43
44
  macro_rules! murmur_group {
44
- ($criterion:expr, $name:literal, $function:path) => {{
45
+ ($criterion:expr, $name:literal, $function:path, $sizes:expr) => {{
45
46
  let mut group = $criterion.benchmark_group($name);
46
- for size in MURMUR_SIZES {
47
+ for size in $sizes {
47
48
  let input = data(size);
48
49
  group.throughput(Throughput::Bytes(size as u64));
49
50
  group.bench_with_input(BenchmarkId::from_parameter(size), &input, |bench, input| {
@@ -58,17 +59,20 @@ fn murmur3(c: &mut Criterion) {
58
59
  murmur_group!(
59
60
  c,
60
61
  "murmur_x86_32_crossover",
61
- hashcodecs::murmur3::murmur3_x86_32
62
+ hashcodecs::murmur3::murmur3_x86_32,
63
+ MURMUR_SIZES
62
64
  );
63
65
  murmur_group!(
64
66
  c,
65
67
  "murmur_x86_128_crossover",
66
- hashcodecs::murmur3::murmur3_x86_128
68
+ hashcodecs::murmur3::murmur3_x86_128,
69
+ MURMUR_SIZES
67
70
  );
68
71
  murmur_group!(
69
72
  c,
70
73
  "murmur_x64_128_crossover",
71
- hashcodecs::murmur3::murmur3_x64_128
74
+ hashcodecs::murmur3::murmur3_x64_128,
75
+ MURMUR_X64_SIZES
72
76
  );
73
77
  }
74
78
 
@@ -6,13 +6,19 @@ use criterion::{BenchmarkId, Criterion, Throughput, criterion_group, criterion_m
6
6
 
7
7
  mod support;
8
8
 
9
- const SIZES: [usize; 16] = [
9
+ const SIZES: [usize; 22] = [
10
10
  16,
11
11
  17,
12
12
  32,
13
+ 33,
13
14
  64,
15
+ 65,
16
+ 97,
14
17
  128,
15
18
  129,
19
+ 160,
20
+ 192,
21
+ 224,
16
22
  240,
17
23
  241,
18
24
  512,