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

github.blog

79 points by sbulaev 6 days ago


lukasgelbmann - 2 days ago

There’s some interesting information in there. Unfortunately the person or LLM writing this got pretty confused right in the introduction already.

> “Suppose […] they type straße and you’ve stored STRASSE. To make these count as matches, you need […]”

Really bad example, because as the article says later on, this casefold crate won’t match those two strings because the ß → ss conversion isn’t done.

> “[str::to_lowercase and case folding] diverge on real characters—ß, İ, final sigma”

The main point is true (case folding is different from lowercasing), but two of the three examples are wrong. The casefold operation that they use maps ß to itself, as does str::to_lowercase. The casefold operation maps İ to U+0069 U+0307 regardless of locale, as does str::to_lowercase.

When I’m reading an article, these kind of mistakes in the introduction make me doubt the accuracy of the whole article. Which is a shame, because again, it’s an interesting write-up. The mistakes also make the article harder to follow, since the examples imply ß is folded to ss.

claudetard - 2 days ago

This is good technical content, but it's obvious that an AI wrote it.

inigyou - 2 days ago

TLDR: they implemented case folding with a lot more SIMD via autovectorization.

> almost every fold preserves the UTF-8 length or shrinks it, but two outliers grow—U+023A (Ⱥ) and U+023E (Ɀ) are 2 bytes each yet fold to 3-byte characters (ⱥ, ɀ)

Fix this by reversing it. Fold ⱥ to Ⱥ instead of the other way around. The search index won't only consist of lowercase characters any more, but that never mattered.

pixelesque - 2 days ago

> We deal mostly with source code, so the text we fold is overwhelmingly ASCII and making it run at memory speed is the single most important thing we can do. Everything else just has to keep the rare non-ASCII path from spoiling it.

Semi-on-topic: I've noticed that many LLMs via coding agents (ChatGPT and Claude at work with my CoPilot account, and DeepSeek 4 and ChatGPT in pi.dev at home) really seem to like using unicode / emoji characters for things like arrows (for things like test value ranges), crosses and ticks (for pass vs fail in test comments), instead of plain ASCII. Codebases are almost exclusively ASCII chars to my knowledge, although they're UTF-8 files.

I'm not yet using agents to write code (only do code reviews, write example prototypes I then copy bits of, and helping craft tests), but I'm likely to get there soon, and I'm sure it's possible to prompt them NOT to do this, but has anyone else noticed this? I wonder if that changes things over time for them if this is a common theme of increased non-ASCII output?

zX41ZdbW - 2 days ago

Interesting, how does it compare with StringZilla? It has highly optimized case-fold and case-insensitive Unicode search kernels as well: https://github.com/ashvardanian/Stringzilla

- 2 days ago
[deleted]
kristianp - 2 days ago

That's the first time I've seen some SIMD code reach more than about 10GB/s. 45 GiB/s is quite something, ASCII only. Of course they're not running the final code on an M4 mac, it will be on a server CPU of some kind. No mention of what sku of M4 mac they're using, it might not matter for single-thread code.

RossBencina - 2 days ago

One thing that wasn't tried is that the ASCII path could build a block-wise bitmap of non-ASCII blocks. Then the unicode pass need only process the contiguous ranges within the bitmap. This would be simpler to implement when combined with inigyou's no-reallocate suggestion.

sdiazthomas - 2 days ago

[flagged]

mohsinq227 - a day ago

[flagged]

cyanregiment - 2 days ago

[dead]