@@ -57,33 +57,32 @@ In this case, I needed a hamming distance library that worked on hexadecimal
5757strings (i.e., a Python ``str ``) and performed blazingly fast.
5858Furthermore, I often did not care about hex strings greater than 256 bits.
5959That length constraint is different vs all the other libraries and enabled me
60- to explore vectorization techniques via ``numba ``, ``numpy ``, and
61- ``SSE/AVX `` intrinsics.
60+ to explore vectorization techniques via ``SSE/AVX `` and ``NEON `` intrinsics.
6261
6362Lastly, I wanted to minimize dependencies, meaning you do not need to install
6463``numpy ``, ``gmpy ``, ``cython ``, ``pypy ``, ``pythran ``, etc.
6564
66- Eventually, after playing around with `` gmpy.popcount ``, `` numba.jit ``,
67- `` pythran.run ``, `` numpy ``, I decided to write what I wanted
68- in essentially raw C. At this point, I'm using raw `` char* `` and
69- `` int* ``, so exploring re-writing this in Fortran makes little sense .
65+ As of v3.0.0, `` hexhamming `` is written in Rust using ` PyO3 < https://pyo3.rs >`_
66+ and ` maturin < https://www.maturin.rs >`_, providing memory safety, GIL release
67+ during computation, and free-threaded Python support while maintaining the same
68+ SIMD-accelerated performance (SSE4.1, AVX2, NEON) .
7069
7170Installation
7271-------------
7372
74- To install, ensure you have Python 3.6 +. Run
73+ To install, ensure you have Python 3.10 +. Run
7574
7675::
7776
7877 pip install hexhamming
7978
80- or to install from source
79+ or to install from source (requires Rust toolchain)
8180
8281::
8382
8483 git clone https://github.com/mrecachinas/hexhamming
8584 cd hexhamming
86- python setup.py install # or pip install .
85+ pip install .
8786
8887If you want to contribute to hexhamming, you should install the dev
8988dependencies
@@ -183,19 +182,45 @@ immutable that is a very slow operation. Use a ``bytearray`` instead, and cast i
183182Benchmark
184183---------
185184
186- Below is a benchmark using ``pytest-benchmark `` with hexhamming==v1.3.2
187- my 2020 2.0 GHz quad-core Intel Core i5 16 GB 3733 MHz LPDDR4 macOS Catalina (10.15.5)
188- with Python 3.7.3 and Apple clang version 11.0.3 (clang-1103.0.32.62).
189-
190- ======================================= =========== ========== ============= ======== ============
191- Name Mean (ns) Std (ns) Median (ns) Rounds Iterations
192- ======================================= =========== ========== ============= ======== ============
193- test_hamming_distance_bench_3 93.8 10.5 94.3 53268 200
194- test_hamming_distance_bench_3_same 94.2 15.2 94.9 102146 100
195- test_check_hexstrings_within_dist_bench 231.9 104.2 216.5 195122 22
196- test_hamming_distance_bench_256 97.5 34.1 94.0 195122 22
197- test_hamming_distance_bench_1000 489.8 159.4 477.5 94411 20
198- test_hamming_distance_bench_1000_same 497.8 87.8 496.6 18971 20
199- test_hamming_distance_bench_1024 509.9 299.5 506.7 18652 10
200- test_hamming_distance_bench_1024_same 467.4 205.9 450.4 181819 10
201- ======================================= =========== ========== ============= ======== ============
185+ Below is a benchmark using ``pytest-benchmark `` with hexhamming v3.0.0
186+ on Apple M-series (ARM64) with Python 3.14 and ``rustc `` 1.85.
187+
188+ String and bytes hamming distance
189+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
190+
191+ ====================================================== =========== ==========
192+ Name Mean (ns) Std (ns)
193+ ====================================================== =========== ==========
194+ hamming_distance_string [3 chars, same] 48.8 10.1
195+ hamming_distance_string [3 chars, diff] 48.4 4.4
196+ hamming_distance_string [64 chars, diff] 88.2 16.0
197+ hamming_distance_string [1000 chars, same] 754.7 251.2
198+ hamming_distance_string [1000 chars, diff] 762.3 75.7
199+ hamming_distance_string [1024 chars, same] 775.1 62.8
200+ hamming_distance_string [1024 chars, diff] 785.0 137.1
201+ hamming_distance_bytes [3 bytes, same] 48.5 5.5
202+ hamming_distance_bytes [3 bytes, diff] 49.0 5.2
203+ hamming_distance_bytes [64 bytes, diff] 50.3 8.4
204+ hamming_distance_bytes [1000 bytes, same] 64.9 5.4
205+ hamming_distance_bytes [1000 bytes, diff] 64.9 11.7
206+ hamming_distance_bytes [1024 bytes, same] 63.2 35.3
207+ hamming_distance_bytes [1024 bytes, diff] 69.1 16.0
208+ check_bytes_within_dist [16 bytes] 52.1 8.9
209+ check_bytes_within_dist [64 bytes] 51.2 23.2
210+ check_bytes_within_dist [127 bytes] 53.4 5.3
211+ ====================================================== =========== ==========
212+
213+ Array API (batch search)
214+ ~~~~~~~~~~~~~~~~~~~~~~~~
215+
216+ =============================================================== ============= ============
217+ Name Mean (ns) Std (ns)
218+ =============================================================== ============= ============
219+ first_within_dist [512 elems × 16B, match at start] 70.0 6.3
220+ first_within_dist [512 elems × 16B, match at end] 721.2 65.7
221+ first_within_dist [16384 elems × 64B, match at end] 48,927.1 8,321.5
222+ best_within_dist [512 elems × 16B] 759.2 108.4
223+ best_within_dist [16384 elems × 64B] 46,295.0 3,793.5
224+ all_within_dist [512 elems × 16B] 776.3 70.9
225+ all_within_dist [16384 elems × 64B] 46,602.1 2,944.3
226+ =============================================================== ============= ============
0 commit comments