![]() |
1
8
AST口译与字节码的主要优势在于操作调度成本,对于高度优化的口译员来说,这开始成为一个真正的问题。”调度”是用来描述开始执行操作(如算术、属性访问等)所需的开销的术语。 一个相当普通的基于AST的解释器应该是这样的:
所以执行代码是为了
在字节码解释器中,您有一个不同的调度模型——而不是虚拟调用,您有一个执行循环,类似于:
与本机代码相比,这仍然具有相当昂贵的调度成本,但比虚拟调度快得多。您可以使用一个名为“computed goto”的GCC扩展进一步提高性能,该扩展允许您删除交换机调度,从而将总调度成本降低到基本上单个间接分支。 除了提高调度成本之外,基于字节码的解释器比AST解释器有许多额外的优势,主要是由于字节码能够像真正的机器一样“直接”跳到其他位置,例如,想象一段这样的代码:
为了在每次执行一条语句时正确地实现这一点,您需要指出执行是要保持在循环中还是停止中,因此执行循环就变得类似于:
当你增加更多形式的流量控制时,这种信号变得越来越昂贵。一旦您添加了异常(例如在任何地方都可能发生的流控制),您就开始需要在甚至基本算术的中间检查这些东西,从而导致开销不断增加。如果你想在现实世界中看到这一点,我鼓励你看看ecmascript规范,在那里它们用一个ast解释器来描述执行模型。
在字节码解释器中,这些问题基本上消失了,因为字节码能够直接表示控制流,而不是通过信号间接地表示。
最后,根据定义,一个AST解释器是递归的,因此必须防止溢出系统堆栈,这对代码中可以循环的量有很大的限制,比如:
在解释器中有8个递归级别(至少),这可能是一个非常大的成本;旧版本的Safari(pre-Squirrelfish)使用了一个AST解释器,因此JS在现代浏览器中只允许几百个递归级别,而在1000个递归级别中是允许的。 |
![]() |
Hatsune Miku · 比较或if语句是否更快[已关闭] 1 年前 |
![]() |
Black Swan · 无法解压缩的值太多(应为2)错误 1 年前 |
![]() |
Kai · 有什么方法可以轻松优化VSCode中的锈迹? 2 年前 |
![]() |
Balfar · 处理NumPy阵列上的循环最有效的方法是什么? 3 年前 |
![]() |
Daniel · C#轻松存储快速访问的大型位矩阵 7 年前 |
|
halbe · 优化音频DSP程序的numpy计算 7 年前 |
![]() |
Afsara · 是否有任何方法不能优化我们的应用程序? 7 年前 |