Skip to content

perf(vector/search): per-field String keys everywhere — wasted hashing & alloc when field count is tiny #674

Description

@mosuka

Round-3 perf push sub-issue (tracked under umbrella #536).

[M] Per-field String keys everywhere — wasted hashing & alloc when field count is tiny

  • Where: QuantizedVectorPool.field_index: HashMap<String, ...>
    (quantized_storage.rs:45); HnswIndexReader.prefetch_index: HashMap<String, ...>
    (hnsw/reader.rs:64); vector_ids: Vec<(u64, String)> everywhere;
    FieldSearchInput.field: String.

  • Current behavior: Every per-field lookup hashes a String (or clones from &str
    via to_string()). In practice indexes have 1-10 vector fields per collection.

  • Why it might be a bottleneck / risk: Memory waste from dual storage (each
    (u64, String) tuple holds a copy of the field name). Hashing a 20-char field name is
    ~50 cycles per call.

  • Reference precedent: Lucene interns field names to integer ords at segment open;
    Tantivy uses FieldId(u32); Qdrant uses payload schema IDs.

  • Data structure (proposed):

    struct FieldId(u16);                       // 65K fields per index
    struct FieldRegistry {
        id_by_name: ahash::AHashMap<String, FieldId>,
        names: Vec<String>,
    }
    // Storage pools key by FieldId:
    pub field_index: SmallVec<[Arc<DocIdMap>; 4]>,   // indexed by FieldId.0
    pub vector_ids: Vec<(u64, FieldId)>,             // (u64, u16) = 16 bytes (12 packed)
    
  • Suggested direction: Introduce per-index FieldRegistry. Storage pools indexed by
    FieldId. String only at public API boundary.

  • Risk / scope: Medium-Large diff; mechanical. Doubles per-field hot-loop speed, cuts
    memory ~30 %.


ID: VS-31 — see ~/.claude/tasks/laurus/20260523_perf_round3_audit/task_list.md for the full Round-3 issue list.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions