是否每次到达行时都会重新解释解释语言的代码?

时间:2009-05-28 19:16:13

标签: bytecode interpreted-language

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

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

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

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

5 个答案:

答案 0 :(得分:5)

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

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

答案 1 :(得分:3)

对于包括perl在内的最新语言,代码在执行前进行了预编译。因此,大多数分析工作只执行一次。

shell不是这种情况,每次执行时都会解释每一行。

答案 2 :(得分:2)

正如所有顾问所知,你的问题的答案是“它取决于。”

你是对的,在一些解释语言中,每次都可以重新解释这一行。我怀疑大多数炮弹都是这样处理的。

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

大多数当前的解释器至少对语言进行标记,因此每次都不需要重新扫描文本。也就是说,像

这样的BASIC-ish程序
 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

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

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

答案 3 :(得分:2)

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

如果在循环内更新了值,那么甚至字节码都需要进行加法运算,而不是使其更有效率。

答案 4 :(得分:2)

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

即使不生成字节代码的解释器也会首先解析您的代码,因为很难一行一行地执行此操作,并且更容易一次完成所有操作。所以一个非常简单的解释器基本上会有一个树,带有两个子节点的“where”循环节点:一个“小于”表达式用于条件,一个块用于循环体。