Perf: SIMD + FFI speedups across hex/bytes APIs - #41
Merged
Conversation
§1 Wire SIMD into check_hexstrings_within_dist for len >= 64 §5 Zero-copy PyBuffer for all byte-input functions §9 set_algo delegates to api::set_algorithm §10 Direct typed params in pyfunction signatures §12 Vec::with_capacity in check_bytes_arrays_all_within_dist §14 Consolidate python.rs thin wrappers over api dispatch 17 new tests for buffer-protocol, SIMD-path, set_algo. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add _with_max variants to all SIMD hex string distance functions (NEON, SSE4.1, AVX2, AVX-512) that check accumulated distance against max_dist after each iteration and return u64::MAX sentinel when exceeded. This restores early-exit performance for the random+tight workload without regressing the similar-strings case. New functions: - neon_simd::hamming_distance_string_neon_pack_with_max - x86_simd::hamming_distance_string_sse_with_max - x86_simd::hamming_distance_string_avx2_with_max - x86_simd::hamming_distance_string_avx512_with_max - lib::hamming_distance_string_dispatch_with_max Performance (1024 hex chars): - random, max=100: 0.192 us -> 0.072 us (2.7x faster, beats baseline) - similar, max=10: 0.193 us -> 0.183 us (no regression) - similar, max=100: 0.195 us -> 0.183 us (no regression) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
📊 Benchmark Comparison Results
➖ 34 benchmarks within noise (click to expand)
Legend: ✅ Faster (>5%) · |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Round of performance work across the Rust SIMD kernels and the PyO3 FFI layer. Measured on Apple M-series (NEON); x86 kernels updated in lockstep.
Highlights (measured)
bytes_arrays_all_within_dist(10k × 128 B)check_bytes_within_dist(4 KB)hamming_distance_bytes(1 KB)check_hexstrings_within_dist(1024 ch, similar)check_hexstrings_within_dist(1024 ch, random, tight max)memoryview/bytearray/ NumPy buffers are now accepted zero-copy.What's in here
SIMD kernels (
src/neon_simd.rs,src/x86_simd.rs,src/native.rs)VPSHUFBnibble-LUT popcount (no more pack → GPRpopcnt).CMPops; hoisted the popcount table out of hot loops.u64::MAXsentinel whenmax_distis exceeded (kills the old 2-pass pattern in batch helpers)._with_maxvariants for all 4 SIMD hex-string kernels + dispatcher, with periodic in-loop threshold checks so SIMD gets the same early-exit benefit the scalar path had.FFI layer (
src/python.rs)check_hexstrings_within_distnow routes ≥64-char inputs through the SIMD dispatcher (previously always scalar).PyBufferfor bytes APIs — acceptsbytes,bytearray,memoryview, NumPy arrays without copying.with_capacityon result vecs, dedup/cleanup inset_algoand friends.Batch APIs (
src/api.rs)first_within_dist/best_within_dist/all_within_distbehind a 64 KB payload gate. Tie-breaking (lowest index) preserved viafold + reduce. Serial fallbacks retained and tested equivalent.Tests
memoryview/bytearray/ NumPy inputs,set_algobehavior, early-exit correctness.cargo fmt,ruffclean.Notes
An initial attempt to gate SIMD vs. scalar on
max_dist >= lenwas a trap: the right choice depends on the actual distance, not a length heuristic. Pushing periodic threshold checks into the SIMD kernels themselves is the clean answer — it wins similar-string similarity search (common case) and random + tight-threshold rejection (previously scalar's strength).Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com