Round-3 perf push sub-issue (tracked under umbrella #536).
[S] Candidate / ResultCandidate are 16 bytes; can be packed to 8
-
Where: hnsw/searcher.rs:262-311 — struct Candidate { id: u64, distance: f32 }
/ ResultCandidate { id: u64, distance: f32 }. Default repr(Rust) pads to 16 bytes.
-
Current behavior: 16 bytes per heap slot. ef_search=64 × ~5 neighbours ≈ 5 KB heap.
-
Why it might be a bottleneck / risk: Heap push/pop touches 5 cache lines instead of
2-3 if packed to 8.
-
Reference precedent: hnswlib (unsigned int, float) = 8 bytes; Lucene
NeighborQueue.encode packs (score, docId) into one long.
-
Data structure (proposed):
// Doc ids ≤ u32::MAX (laurus already implicitly assumes this elsewhere).
// f32 has order-preserving bits for positive values; sign-flip negative for total order.
#[repr(transparent)]
struct PackedCandidate(u64);
// bits 63..32 = encoded f32 distance (order-preserving)
// bits 31..0 = u32 doc_id
// Native `Ord` on u64 → correct heap order without partial_cmp / NaN guards.
-
Suggested direction: Bound doc_id to u32 (current vector_count <= u32::MAX). Use
packed candidate. Heap operations ~1.5× faster in microbench.
-
Risk / scope: Small. Doc id widening to u32 is the only API touch.
ID: VS-23 — see ~/.claude/tasks/laurus/20260523_perf_round3_audit/task_list.md for the full Round-3 issue list.
Round-3 perf push sub-issue (tracked under umbrella #536).
[S]
Candidate/ResultCandidateare 16 bytes; can be packed to 8Where:
hnsw/searcher.rs:262-311—struct Candidate { id: u64, distance: f32 }/
ResultCandidate { id: u64, distance: f32 }. Defaultrepr(Rust)pads to 16 bytes.Current behavior: 16 bytes per heap slot. ef_search=64 × ~5 neighbours ≈ 5 KB heap.
Why it might be a bottleneck / risk: Heap push/pop touches 5 cache lines instead of
2-3 if packed to 8.
Reference precedent: hnswlib
(unsigned int, float)= 8 bytes; LuceneNeighborQueue.encodepacks (score, docId) into onelong.Data structure (proposed):
Suggested direction: Bound doc_id to u32 (current vector_count <= u32::MAX). Use
packed candidate. Heap operations ~1.5× faster in microbench.
Risk / scope: Small. Doc id widening to u32 is the only API touch.
ID:
VS-23— see~/.claude/tasks/laurus/20260523_perf_round3_audit/task_list.mdfor the full Round-3 issue list.