前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Rust 视界】toml-edit 优化之旅

【Rust 视界】toml-edit 优化之旅

作者头像
张汉东
发布2021-10-13 11:34:36
6260
发布2021-10-13 11:34:36
举报
文章被收录于专栏:Rust 编程Rust 编程

原文[1]

toml_edit是一个保留格式(在修改用户的Cargo.toml时,能保留格式)的TOML crate,允许用户修改.toml文件。

优化之前

代码语言:javascript
复制
toml_edit 8.7us 271us
toml_edit::easy 20.7us 634us

优化之后

代码语言:javascript
复制
toml_edit 4.0us 149us
toml_edit::easy 5.0us 179us

上下文:

该作者是 cargo-edit 的核心贡献者,现在正致力于将 cargo-add 合并到 cargo 的工作中,其中对 toml 的修改要用到 toml_edit 这个库,他们已经把相关的工作都做完了,只剩下最后都性能优化。这篇文章就是 作者对 toml_edit 性能优化的记录。

性能之旅:

1. 要确定你的优化目标。

作者之前并不确定可以从 toml_edit 中可以挤出多少性能,但是Alex Crichton帮助他确定了这个目标,他特别指出Cargo的解析器,是一个影响用户的瓶颈,这个结果是在toml-rs 分析时展示出来的。因此,toml_edit 至少应该和 toml_rs有同样的速度,他们还想进一步优化toml_rs

2. 依靠性能之书[2] 来帮助开始profile,选择了callgrind和kcachegrind作为可视化工具。

3. 使用 kstring[3] ,来优化字符串key。

默认情况下,kstring :

  • 内联字符串存储总共 16个字节
  • max_inline 特性选择存储总共 23 个字节,对于小字符串来说会很慢
  • 以Box的形式存储堆字符串
  • 使用Arc,它用Ref-counting的成本代替了分配的成本

4. 要注意第三方解析便利性背后的成本

解析器组合器,如nom或combined,使语法转换为代码变得容易,但也很容易隐藏大量的成本:

  • 不必要的分配
  • 缺少批处理

他优化解析器的 https://github.com/ordian/toml_edit/pull/209

5. 将字符和字符串的操作换成按字节操作,并且根据情况在某些安全的情况下,使用 uncheck 的方法来避免 utf-8 校验。 PR在这里[4]

6. 良好错误处理背后的代价。

toml_edit 之前的解析器用的是 combine,它的特点是错误处理非常细致,将检查每个选择并合并错误。它优先考虑在字符串中最早出现的错误,并合并发生在相同点的错误。这样做的问题是,即使没有面向用户的错误发生,错误处理的逻辑也会让你付出代价。

作者要优化他还有很多选择,比如放弃 combine,使用nom或者手写parse (性能优化效果将最大),但是他选择继续使用 combine,但是用 dispatch! (可以迅速实施改变)来代替map。这样的选择算是小步迈进。PR[5]

7. serde的隐藏成本

serde对toml文件中每个字符串进行解析,看它是否可能是一个日期。没有Datetime的文件必须为它的存在付出代价。所以作者将使用一个专门的结构体来优化这种情况。PR[6]

默认情况下,serde检查每个未标记的枚举的变体,看它是否有效。作者使用 手动实现 serde::Deserialize trait 来优化这种情况,而避免 derive 自动实现。PR[7]

有哪些优化是失败的呢?

不是所有的修复都是成功的。不幸的是,失败的尝试通常不会被很好地记录下来,因为它们可能不会被记录到PR中。

这里作者凭记忆罗列了一些失败的尝试:

  1. 批处理优化,收益比较小
  2. 想进一步优化KString,反而变慢了
  3. 尝试将 combine 迁移到 nom,目前正在努力

最后,发现了这句话:感谢 Futurewei 对这项工作的赞助

参考资料

[1]

https://epage.github.io/blog/2021/09/optimizing-toml-edit/: https://epage.github.io/blog/2021/09/optimizing-toml-edit/

[2]

性能之书: https://nnethercote.github.io/perf-book/profiling.html

[3]

kstring: https://github.com/cobalt-org/kstring

[4]

这里: https://github.com/ordian/toml_edit/pull/219/

[5]

PR: https://github.com/ordian/toml_edit/pull/222

[6]

PR: https://github.com/ordian/toml_edit/pull/226

[7]

PR: https://github.com/ordian/toml_edit/pull/227

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-10-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 觉学社 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 上下文:
    • 性能之旅:
      • 参考资料
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档