Add SIMD window to key digest search - #32
Merged
Merged
Conversation
Base automatically changed from
claude/readonly-db-optimization-19c03f
to
main
August 16, 2026 05:34
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.
Note
Stacked on #31 (struct key comparer specialization) — review the last commit only. Retarget to
mainafter #31 merges.Summary
Replaces the tail of the digest binary search with a branch-free SIMD count. The classic binary search carries one hard-to-predict branch per level; this change runs the branchy search only down to a 32-element window and finishes with a
Vector128count of digests below the probe (DigestSearch.LowerBound), then resolves the run of equal digests with full key comparisons.Two details worth reviewing:
[max-32, max): it always stays inside the digest array, and any element belowminit covers is< keyDigestby the binary-search invariant, so counting it keeps the result exact.DigestSearch.IsAccelerated. The lower-bound restructure only pays off together with the SIMD window — losing the classic search's early digest-equality exit costs more than the restructure alone gains (measured: 16.4 → 22.3 µs on point lookups with the SIMD path disabled). netstandard2.1 (Unity) and non-SIMD hardware therefore keep the existing mixed digest binary search unchanged.Benchmark
The existing
RandomKeysbenchmark re-seeds its LCG every op, so the same 1000-key sequence repeats and the branch predictor gradually memorizes its branch history — it no longer models unpredictable access. This PR adds aRandomKeys_NoRepeatvariant that carries the seed across ops (genuinely non-repeating), which is the closest model of real random access; the measured 86 µs vs 30 µs against the repeating variant on identical code shows how much the predictor was learning.M4 / .NET 10, ShortRun, paired runs (machine noise ±2-3 µs; worth re-verifying with the usual solo-run protocol):
The trade: ~+2-4% on fully-predictable access patterns, -22% on unpredictable ones. Real workloads (keys driven by app logic) sit closer to the NoRepeat end than to a repeating 1000-key loop.
Tests: 79/79 pass, including new coverage for digest-collision runs (ascii keys sharing an 8-byte prefix) and >32-entry nodes on the SIMD path (
KeyDigestSearchTest). No file-format change; netstandard2.1 byte-for-byte identical behavior.🤖 Generated with Claude Code