假设用户搜索咖啡馆,而您的语料库中包含咖啡馆,或者用户键入straße,而您存储了STRASSE。要使这些字符串算作匹配,您需要一个消除大小写差异的规范形式,以便两个仅在比较相同的情况下不同的字符串。
该表单是大小写折叠,它显示在文本匹配而不是显示的任何位置:搜索引擎、正则表达式(? i)标志、不区分大小写的用户名和主机名。这是一个基本的操作,但在GitHub,我们经常运行它。GitHub的代码搜索引擎Blackbird索引了超过1.8亿个存储库,超过480TB的源代码。
在我们提取ngram并构建索引之前,每个字节都是大小写折叠的,对于每个潜在的查询结果,都需要另一个(隐式或显式)大小写折叠操作来定位匹配项。在这个尺度上,即使是基本操作的速度也开始起作用。这篇文章是关于我们如何快速完成的,它从违反直觉的地方开始: ASCII快速路径中最大的胜利来自于删除优化,而不是添加优化。
事实证明,在没有分支的情况下扫描整个缓冲区比在第一个非ASCII字节处提前停止更快。我们将结果开源为名为casefold的Rust crate。
折叠不是小写字母很容易达到str:: to_lowercase,但小写字母和折叠是不同的操作,具有不同的目标:小写字母用于显示,并且与区域和上下文相关:希腊语最后的sigma小写字母在单词末尾为ς, σ在其他地方,土耳其语I小写字母与英语I不同。