OFICIAL GitHub Blog

Don’t stop early: Case-folding source code at memory speed

What happened
Based on GitHub Blog · Jul 31, 2026

GitHub open-sourced casefold, a Rust crate optimizing case-folding for code search at over 45 GiB/s per core by eliminating early-exit branches and using branch-free loops.

Don’t stop early: Case-folding source code at memory speed
GitHub Blog — GitHub
Key points
·
How a branch-free loop and byte-space arithmetic let GitHub case-fold every byte of code search at >45 GiB/s on a single core.
·
Suppose a user searches for café and your corpus contains CAFÉ, or they type straße and you’ve stored STRASSE.
·
To make these count as matches, you need a canonical form that erases case distinctions, so that two strings which differ only in case compare equal.
·
That form is case folding, and it shows up wherever text is matched rather than displayed: search engines, regex (?i) flags, case-insensitive usernames and hostnames.
Key numbers
·
GitHub’s code search engine Blackbird indexes over 180 million repositories, requiring case-folding for every byte of source code to ensure case-insensitive matches.
·
Removing data-dependent control flow allows vectorization, enabling the loop to process 16 bytes at a time.
·
Case folding preserves UTF-8 length for most characters, but two outliers—U+023A (Ⱥ) and U+023E (Ɀ)—expand to three bytes when folded.

GitHub’s code search engine Blackbird indexes over 180 million repositories, requiring case-folding for every byte of source code to ensure case-insensitive matches. Case folding converts text to a canonical form for comparison, distinct from locale-sensitive lowercasing, and is essential for operations like search engines and case-insensitive usernames. The challenge was optimizing this basic operation at scale, where even small speed improvements significantly impact performance.

The crate casefold achieves over 45 GiB/s on a single core by using a branch-free loop that processes ASCII bytes without early exits. Traditional approaches, which stop at the first non-ASCII byte, run at just 3 GiB/s due to branch penalties. Removing data-dependent control flow allows vectorization, enabling the loop to process 16 bytes at a time. Benchmarks show that branch-free loops outperform even optimized two-pass methods, demonstrating that branches are the primary bottleneck in hot loops.

Case folding preserves UTF-8 length for most characters, but two outliers—U+023A (Ⱥ) and U+023E (Ɀ)—expand to three bytes when folded. To handle this, casefold allocates a secondary buffer sized for worst-case growth (1.5× input size) upfront, avoiding incremental reallocations. The design minimizes branches by moving unchanged byte runs in bulk and writing folded characters unconditionally, deferring length adjustments until the end.

The non-ASCII path leverages a sparse 1776-byte lookup table derived from Unicode 16.0’s 1484 simple-fold mappings. A one-bit-per-page bitmap quickly rejects non-foldable characters, while a cumulative-popcount side table locates foldable entries only when necessary. This structure prioritizes the common case—no fold—by enabling a single bit test from leading UTF-8 bytes, ensuring the hot path remains branch-light and efficient.

Original source → Deals on Clipraptor.com →