2

假设没有为程序生成字节码,例如在 Ruby、Perl 或 PHP 中,在这种情况下,每次执行再次到达第 1 行时,是否会重新解释下面的第 1 行?

while ($indexArrayMoviesData < $countArrayMoviesData + $countNewlyAddedMoviesData) {
  # do something
}

也就是说,如果循环运行 100,000 次,那么该行将被重新解释 100,000 次?

如果是这样,字节码的创建不仅有助于程序的初始启动,而且在执行期间也有帮助?(因为代码不需要再次重新解释)

4

5 回答 5

5

通常,它将被转换为字节码,然后执行该字节码。

但是以 PHP 为例,字节码会在每个请求/页面视图上重新生成。除非您安装字节码(或在 PHP 中经常调用的操作码)缓存,例如 XCache、APC 或 EAccelerator。

于 2009-05-28T19:20:38.447 回答
3

对于最近的语言,包括 perl,代码在执行之前会被预编译。所以大部分分析工作只执行一次。

对于 shell 而言,情况并非如此,它们每次执行时都会解释每一行。

于 2009-05-28T19:22:24.420 回答
2

正如所有顾问所知,您的问题的答案是“视情况而定”。

您是对的,在某些解释语言中,该行可能每次都被重新解释。我怀疑大多数贝壳都是这样处理的。

Basic 的原始版本也是这样做的。

大多数当前的解释器至少会标记语言,这样就不需要每次都重新扫描文本。也就是说,一个基本的程序,如

 00010 LET A=42
 00020 DO WHILE A > 0
 00025    LET A = A - 1
 00030 ENDDO

至少会将其转换为关键字的小标记和变量的地址,例如

 LET    $0003, 42
 LABEL  00020 
 LETEST A, 0
 IFTRUEGOTO   00030
 SUB    $0005, $0003, 1
 GOTO   00020
 LABEL  00030

其中翻译中的每个大写单词在内部都是一个整数。这样,有一个单一的词法分析传递来翻译它,然后解释器能够只解释标记值。

当然,一旦你走到那一步,你就会发现自己在想“哎呀,为什么不使用真正的操作码呢?”

于 2009-05-28T19:17:28.033 回答
2

如果解释器是明智的,它希望检查 $countArrayMoviesData 或 $countNewlyAddedMoviesData 在循环期间是否被更改,如果不是,则可以计算并保留总和。

如果值在循环内更新,那么很可能即使是字节码也需要进行加法操作,而不是提高效率。

于 2009-05-28T19:22:24.420 回答
2

很少有口译员会这样做。一个例子是用于 Hypercard 的古老的、不再使用的 Hypertalk 解释器,您实际上可以在其中以编程方式重写代码的文本(它只是一个字符串!)

即使是不产生字节码的解释器也会首先解析你的代码,因为很难逐行解析,而一次性完成则要容易得多。因此,一个非常简单的解释器基本上会有一棵树,其中一个节点用于“where”循环和两个子节点:一个“小于”表达式用于条件,一个块用于循环体。

于 2009-05-28T19:23:41.047 回答