2009-05-28 83 views
2

假設沒有爲程序生成字節碼,就像在Ruby,Perl或PHP中一樣,在這種情況下,下面的第1行是在每次執行再次到達第1行時重新解釋的?是解釋語言的代碼在每次到達時重新解釋?

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

也就是說,如果循環運行100,000次,那麼該行將被重新解釋100,000次?

如果是這樣,字節碼的創建不僅有助於他程序的初始啓動,還有助於執行期間? (因爲代碼不需要重新解釋)

回答

5

通常,它將被轉換爲字節碼,然後該字節碼將被執行。

但是以PHP爲例,字節碼在每個請求/頁面視圖上重新生成。除非你安裝了一個字節碼(或者在PHP中經常調用的操作碼)緩存,例如XCache,APC或EAccelerator。

2

正如所有顧問所知,您的問題的答案是「它取決於」。

你是對的,在一些解釋型語言中,每行可能會重新解釋該行。我懷疑大多數炮彈大致這樣處理它。

Basic的原始版本也是這樣做的。

大多數當前口譯員將至少標記語言,以便文本不需要每次重新掃描。也就是說,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 

其中大寫每個單詞在翻譯中是內部的單個整數。這樣,有一個詞法分析階段可以翻譯它,然後解釋器能夠解釋這些標記值。

當然,一旦你走了那麼遠,你會發現自己在想「哎呀,爲什麼不使用真正的操作碼?」

+0

你的意思是顧問喜歡回答「它取決於」作爲正式答案嗎?如何在命令行上運行Ruby?或PHP在命令行上運行? – 2009-05-28 19:19:37

+0

這真是一個關於顧問的笑話。顧問經常回答「依賴」,因爲他們現在還不夠了解,但不想回答「我不知道」。 – 2009-05-28 19:29:04

+0

我不知道在執行之前沒有標記的BASIC。甚至基於CP/M的基礎知識,老蘋果的基礎知識(包括FP(來自微軟)和Int(來自Woz!))。 – Javier 2009-05-28 19:55:56

3

對於最近的語言,包括perl,代碼在執行之前被預編譯。所以大部分分析工作只進行一次。

這不是shell的情況,它在每次執行它們時解釋每一行。

2

如果解釋器是明智的,它會希望檢查$ countArrayMoviesData或$ countNewlyAddedMoviesData是否在循環過程中被更改,如果它們不是那麼可以計算和保存總和。

如果值在循環內更新,那麼很可能即使是字節碼也需要進行加法操作,而不是使其更有效。

2

很少有口譯員會這樣做。一個例子就是已經不再使用的Hypercard解釋器,它可以通過編程方式實際重寫代碼的文本(它只是一個字符串!)

即使是不生成字節碼的解釋器也會先解析你的代碼,因爲很難一行一行地完成這個任務,並且一次完成所有操作都很容易。因此,一個非常簡單的解釋器基本上會有一棵樹,其中有一個用於帶有兩個子元素的「where」循環的節點:一個「小於」表達式和一個循環體塊。

+0

Perl會這樣做,執行句法樹而不是字節碼。 – Javier 2009-05-28 19:53:35

+0

我甚至不打賭HyperCard做到了。看來,至少2.x JIT編譯它的代碼。它只是透明地重新編譯代碼,如果你曾經使用代碼改變過一個對象的腳本。類似地,「do」命令可以簡單地獲取當前上下文,然後根據需要編譯您提供的字符串,指向周圍腳本的堆棧。 – uliwitness 2015-12-14 13:23:20