Skip to content

Codegen: SipHash dominates CodeGenContext's internal naming/comment maps #396

Closed

Description

@th0114nd

The problem

CodeGenContext's internal bookkeeping — package/message name deconfliction, doc-comment lookup, oneof/message indexing (context.rs, comments.rs) — is built fresh from the whole descriptor set on every generate() call, using std::collections::HashMap. That defaults to SipHash, which is designed to resist hash-flooding from untrusted input.

This data only ever comes from trusted, locally-generated .proto descriptors (protoc/buf output), never attacker-controlled input, so SipHash's DoS resistance buys nothing here, and its cost is measurable.

Measured

Sampling (sample, macOS) a real ~2900-crate, ~2900-package codegen run against a large IDL corpus, sorted by top-of-stack leaf frame:

core::hash::sip::Hasher::write            6338 samples
hashbrown::raw::RawIterRange::fold_impl   1438
core::hash::BuildHasher::hash_one         1034 (+295 +54 +11 elsewhere)
HashMap::insert (several monomorphizations)  ~1067 combined
RawTable::reserve_rehash                   ~639 combined

Hashing-related frames were roughly 17% of all samples — the single largest cost bucket in the profile, ahead of any actual codegen logic (token generation, prettyplease formatting, etc.).

Fix

Swap context.rs and comments.rs's internal maps to a non-cryptographic hasher. foldhash is already resolved transitively via hashbrown, so this is a direct dependency on something already in the tree, not new third-party code.

oneof.rs's maps were tried too but reverted: they leak through public signatures in message.rs/view.rs/lazy_view.rs, too broad a blast radius for what should be a purely internal, output-invariant change. Left as std::HashMap for now — a future PR could thread a type alias through those signatures if it's worth the diff.

Verification

Output-invariant by construction (the change only affects which hash function internal maps use, never what gets generated) — confirmed with a full hash-diff of a real 2895-crate generation run, before and after: byte-for-byte identical. All existing buffa-codegen tests pass unmodified.

PR to follow.

Activity

  1. th0114nd commented on Aug 30, 2026

    @th0114nd
    ContributorAuthor

    Closing alongside #398 — see that PR for the reasoning. Not worth separate review attention on its own; focusing on #397/#399 instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions