Round-3 perf push sub-issue (tracked under umbrella #536).
[M] Score representation is f32 everywhere — bf16/fp16 candidate storage would halve memory pressure
- Where:
Candidate.distance: f32, VectorHit.score: f32, FieldHit.score: f32,
SearchHit.score: f32. All f32.
- Current behavior: Search candidate buffers at 4 B / score. ef_search=256 →
intermediate buffers up to 256 × 16 B = 4 KB/query. 1000 queries × 100 segments → 400
MB pressure.
- Why it might be a bottleneck / risk: f16 (or u16 if scores normalised to
[-1,1])
halves that. Precision loss in monotone-only ranking is negligible.
- Reference precedent: Lucene 9 internal scorers in
int (rank-only); Qdrant supports
f16/bf16 for embeddings.
- Suggested direction: bf16 candidate storage option for HNSW intermediate state (not
final score). Keep f32 in LRS1 sidecar and final API.
- Risk / scope: Medium. Requires bf16 SIMD or fall back to f32 expand at compare.
ID: VS-27 — 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).
[M] Score representation is f32 everywhere — bf16/fp16 candidate storage would halve memory pressure
Candidate.distance: f32,VectorHit.score: f32,FieldHit.score: f32,SearchHit.score: f32. All f32.intermediate buffers up to 256 × 16 B = 4 KB/query. 1000 queries × 100 segments → 400
MB pressure.
[-1,1])halves that. Precision loss in monotone-only ranking is negligible.
int(rank-only); Qdrant supportsf16/bf16 for embeddings.
final score). Keep f32 in LRS1 sidecar and final API.
ID:
VS-27— see~/.claude/tasks/laurus/20260523_perf_round3_audit/task_list.mdfor the full Round-3 issue list.