假设没有为程序生成字节码,比如在Ruby,Perl或PHP中,在这种情况下,每次执行再次到达第1行时,下面第1行是重新解释的吗?
while ($indexArrayMoviesData < $countArrayMoviesData + $countNewlyAddedMoviesData) {
# do something
}
也就是说,如果循环运行100,000次,那么该行将被重新解释100,000次?
如果是这样,字节码创建不仅有助于程序的初始启动,还有助于执行期间? (因为代码不需要再次重新解释)
答案 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”循环节点:一个“小于”表达式用于条件,一个块用于循环体。