perf(diskann): reuse VisitedSet across searches, add search_with and allocation regression test#683
Open
ohdearquant wants to merge 2 commits into
Open
Conversation
added 2 commits
July 12, 2026 12:52
Fixes ruvnet#677 Co-Authored-By: Leo <noreply@khive.ai>
…allocation regression test Fixes ruvnet#677 Co-Authored-By: Leo <noreply@khive.ai>
Contributor
Author
|
CI note — the red checks on this PR are not caused by this diff:
The DiskANN build and test jobs for this change all pass. |
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
This change removes the per-query
VisitedSetallocation from hotDiskAnnIndex::search()calls while preserving the existing API and result ordering.DiskAnnIndex::search_with, which accepts a caller-ownedVisitedSetand routes directly throughVamanaGraph::greedy_search_fast.visitedfield with a boundedstd::sync::Mutex<Vec<VisitedSet>>pool. The normal single-threaded path checks out and returns one preallocated set. An empty or contended pool falls back to a fresh set, and the pool retains at most four sets.u64generation reaches its maximum.search_withand the pre-fix allocating algorithm shape.Fixes #677
Measurements
bench_search_hotbuilds seeded random unit vectors withd=128, then measures 2,000 single-threaded searches atk=10in a release build. Build settings areR=4,L_build=8,L_search=64, andalpha=1.0. The table reports the median of three runs per configuration. Additional raw samples are retained where visible host variance prompted repeat collection.Allocation values are the exact backing storage requested by the old
VisitedSet::newpath: then * size_of::<u64>()generation array plus the bit-vector storage. The after value is the steady-state visited-state allocation after one warmup. The regression test additionally asserts that 100 hot searches allocate zero blocks at or above the 2,000,000-byte generation-array size and less than 300,000 bytes total for all other search output and candidate storage combined.Hardware: Apple M2 Max, 32 GB RAM, macOS 26.6. Searches were single-threaded and binaries used the Cargo release profile.
Reproduce with
cargo run --release -p ruvector-diskann --example bench_search_hot. The benchmark commit predates the fix commit on this branch, so before numbers come from checking out the benchmark commit alone.Compatibility and safety
The public
searchsignature and behavior remain unchanged. The newsearch_withAPI allows explicit reuse where callers want to own query scratch state. Search candidates, exact re-ranking, and ordering are unchanged.The pool uses only the standard library, adds no dependency, and does not assume threads exist. This keeps the single-thread pool path suitable for
wasm32. The upstream crate baseline currently failswasm32-unknown-unknowncompilation ingetrandombecause its JavaScript feature is not enabled, so no new wasm target regression was introduced or masked here.Verification
cargo fmt -p ruvector-diskanncargo clippy -p ruvector-diskann --all-targets -- -D warningscargo test -p ruvector-diskanncargo build --release -p ruvector-diskann --examples, on both the unfixed and fixed source