“德语字符串”在魔法书(Spellbook)中的优化

主要观点

  • 介绍了为 Helix 编辑器编写的 Rust 拼写检查库 Spellbook,它是对 Hunspell 的重写,接口简洁,可从 Hunspell 字典文件实例化字典并检查单词。
  • 重点讨论 Spellbook 中字符串的表示及优化,以节省内存,如从String切换到Box<str>,引入“German strings”(UmbraString)优化。
  • 详细阐述了UmbraString的实现,包括各种操作函数(如lenis_emptyfromas_slice等)的实现,以及在内存使用和性能方面的优化效果。
  • 还提到将“German string”优化应用于FlagSet,并讨论了相关的陷阱和注意事项,如使用MaybeUninit<T>避免未定义行为,以及 null 指针优化可能导致的奇怪行为。

关键信息和重要细节

  • Spellbook 工作流程:检查单词时在哈希表中查找单词,哈希表中存储每个“stem”的条目,通过规则定义的标志进行前缀和后缀变换。
  • Rust 中字符串的表示:String类型灵活可修改,由指针、长度和容量组成;&str和切片是“fat pointer”,包含指针和元数据。
  • Box<str>的优势:对于不修改的字符串,可节省存储capacity的 8 字节。
  • “German strings”(UmbraString):用小于usize的整数类型存储长度,节省空间,可通过union实现短字符串内联存储和长字符串指针存储,还可优化比较操作。
  • UmbraString的实现细节:包含长度、前缀和后缀字段,通过各种函数实现字符串的创建、复制、转换为字节切片等操作,注意处理零值和未初始化数据。
  • 内存节省效果:在不同场景下与Box<str>相比,节省了大量内存,减少了堆交互,如在创建en_US字典示例中,节省了约 300kb 内存。
  • FlagSet的优化:类似UmbraString,构建“UmbraSlice”类型存储标志集,节省内存和减少分配。
  • 注意事项:使用MaybeUninit<T>避免未定义行为,避免在处理NonZeroU16时因零值导致的奇怪行为,Miri 可帮助检测未定义行为。

总结来说,通过对 Spellbook 中字符串表示的优化,实现了内存节省和性能提升,同时也深入探讨了 Rust 中的相关概念和技巧。

阅读 21
0 条评论