这是一系列关于在 Rust 中推动编程语言解释器性能的博客文章的一部分。
什么?谁?
作者的博士研究是关于 AST 解释器的运行时性能,去年发表了“AST 与字节码:元编译时代的解释器”论文,比较了基于两种不同元编译系统(GraalVM 和 RPython)的 AST 和字节码解释器,得出 AST 解释器性能良好的结论。有人质疑 AST 解释器是否只在依赖高级语言的元编译系统上表现好,作者尝试在 Rust 中让解释器性能达到现有水平甚至更好。Nicolas Polomack 编写了 som-rs 解释器,作者对其进行性能优化,几个月后取得了显著成果。
本周发生了什么?
- 对于 SOM 语言的解释器,循环是方法调用,速度不是最快的,通常可以通过降低(如在字节码级别或直接在解释器中处理)来提高性能,作者已经为
whileTrue:
实现了一些优化。 - 常见的循环方式
Integer>>#to:do:
目前没有被特殊处理以获得更好性能,作者决定将其实现为一个原始函数(primitive),即直接在解释器中处理为特殊情况。实现的to:do:
原始函数通过检查栈上的参数类型来执行循环体,但缺少执行块的关键部分。 - 执行块的方式是将 50 个新的块帧压入栈中,但这样会导致解释器出错,因为每个方法或块都有返回值,而这里不需要关心块的返回值,需要在每个块执行后弹出栈顶值。作者通过添加
am_i_ugly
标志来解决这个问题,但代码很丑陋且在某些情况下会导致性能下降。 - 更好的解决方案是执行一个自我清理的修改版本的块,通过在每个
RETURN
之前添加POP
来清空栈,但这需要修改字节码集,增加了复杂性和开发时间。也可以在编译时生成块,但由于需要在运行时访问块的来源,实现起来并不容易。最终采用在运行时创建修改块的方案,取得了巨大的性能提升。
我们学到了什么?
- 解释器的设计很重要,选择不同的执行方式会影响性能。
- 优化循环操作可以显著提高运行时性能。
- 快速简单的解决方案往往并不简单,需要对系统和解释器设计有深入的了解。
感谢 Stefan Marr 的反馈和帮助,作者将继续分享相关内容。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。