是否有代碼優化由同一版本做過任何區別: 甲骨文Java編譯器 Apache的Java編譯器 IBM Java編譯器 OpenJDK的Java編譯器。 如果有什麼代碼會演示不同的優化?還是他們使用相同的編譯器?如果沒有已知的優化差異,那麼我可以在哪裏找到關於如何測試編譯器以進行不同優化的資源?是否有編譯器的區別 - Java的
回答
相同版本的代碼優化是否存在差異:Oracle Java編譯器Apache Java編譯器IBM Java編譯器OpenJDK Java編譯器。
儘管編譯器可能非常不同,javac
幾乎沒有優化。主要優化是恆定內聯,這是在JLS中指定的,因此是標準的(除了任何錯誤)
如果有什麼代碼會證明不同的優化?
你可以這樣做。
final String w = "world";
String a = "hello " + w;
String b = "hello world";
String c = w;
String d = "hello " + c;
System.out.prinlnt(a == b); // these are the same String
System.out.prinlnt(c == b); // these are NOT the same String
在第一種情況下,常量被內聯並且在編譯時串聯字符串。在第二種情況下,連接在運行時執行並創建一個新的字符串。
還是他們使用相同的編譯器?
不,但99%的優化是在運行時由JIT執行的,因此這些對於給定版本的JVM是相同的。
如果沒有已知的優化差異,那麼我可以在哪裏找到關於如何測試用於不同優化的編譯器的資源?
我會很驚訝,如果有一個,因爲這聽起來不太有用。問題是JIT優化了預先構建的字節代碼模板,如果您嘗試優化字節代碼,您最終可能會混淆JIT並導致代碼較慢。即沒有考慮將運行的JVM就無法評估優化。
以VIP班級字符串+1爲例:) –
不,他們不使用相同的編譯器。我無法對優化和東西發表太多評論,但下面是編譯器在工作中的不同之處。
public class Test {
public static void main(String[] args) {
int x = 1L; // <- this cannot compile
}
}
如果您使用標準的java編譯器,它會引發編譯錯誤,並且不會創建類文件。
但是,如果你使用的Eclipse Java編譯器ECJ,它不僅會拋出同樣的編譯錯誤,但也將創建一個類文件(YES,對於不可編譯的代碼,這使得歐洲法院一類文件,我不會說錯,但有點棘手),看起來像這樣。
public static void main(String[] paramArrayOfString)
{
throw new Error("Unresolved compilation problem: \n\tType mismatch: cannot convert from long to int.\n");
}
話雖如此,這只是介於2個編譯器之間。其他編譯器可能有自己的工作方式。
P.S:我把這個例子從here。
這是一個有效的觀察,但也許值得一提的是,ECJ並不是一個「正確的」編譯器,因爲它故意違反了一些規則。在這個例子中(就像你說的那樣),類不能編譯,而ECJ無論如何都會生成字節碼。在給定相同輸入的情況下產生不同形式的合法/正確輸出的編譯器之間比較有趣的比較。但是,這很難舉例說明。 –
@AndrzejDoyle - 我在大多數情況下都同意你的看法,但我真的不想把ECJ稱爲「不正確的編譯器」,因爲它故意違反了一些規則。這是我的看法,但每個人都有他們的觀點,我尊重你的觀點! – SudoRahul
我花費大量時間編寫的唯一編譯器是javac
(正如其他人指出的那樣,在急切優化方面做得很少)和Eclipse編譯器。在編寫Java反編譯器時,我觀察到Eclipse編譯代碼的一些(通常令人沮喪的)差異,但並不是很多。其中一些可以被認爲是優化。其中:
Eclipse編譯器似乎執行至少一些重複的代碼分析。如果兩個(或更多?)代碼塊分支到分離但等同的代碼塊,則等效目標塊可以平鋪爲具有多個條目跳轉的單個塊。我從來沒有見過
javac
執行這種類型的優化;等效塊總是會被放出。我記得所有的例子都發生在switch
聲明中。此優化減少了方法大小(因此減小了文件大小),這可以提高負載和驗證時間。它甚至可能會導致解釋模式中的性能提高(特別是如果解釋器執行內聯操作時),但我想這樣的改進會很輕微。我懷疑這種方法一旦被JIT編譯就會有所作爲。它也使反編譯更加困難(grrr)。基本塊通常以與
javac
完全不同的順序發射。這可能只是編譯器內部設計的一個副作用,也可能是編譯器試圖優化代碼佈局以減少跳轉次數。這是我通常留給JIT的那種優化,而且這種理念似乎對javac
工作正常。
- 1. 是否有一個Java SWF編譯器?
- 2. 是否有Java到Flash編譯器?
- 3. lex編譯器和C編譯器的區別?
- 4. LLVM中編譯器和編譯器驅動程序的區別?
- 5. 是否有Groovy GPath編譯器的XPath?
- 6. GNU Java編譯器是否支持JNA?
- 7. Swift的泛型是否分別編譯?
- 8. 是否有繞過編譯的Java解釋器?
- 9. 編譯器內是否有預編譯IPV6的標誌
- 10. 微軟C/C++編譯器的C編譯器和C++編譯器有什麼區別?
- 11. 這些Scripts.Render語句之間的編譯器有什麼區別?
- 12. 不同的編譯器之間有什麼區別
- 13. 是否有Java程序片段可以在JRE 6上使用Java 5編譯器進行編譯,但是不能使用Java 6編譯器進行編譯?
- 14. 在視圖和編輯器中定義DropTarget是否有區別?
- 15. //和m //是否有區別?
- 16. $ @和$ $是否有區別?
- 17. 調試和編譯有什麼區別?
- 18. 是否有Java的Coffeescript?換句話說,X被編譯爲Java
- 19. 編譯器是否對Boost.Build有用?
- 20. 是否有內聯網頁編譯器?
- 21. 編譯器和鏈接器之間有什麼區別?
- 22. Mono C#編譯器和MS C#編譯器關於作用域的區別
- 23. C++編譯器是否能識別2的冪次?
- 24. OCaml編譯器是否支持真正的模塊別名?
- 25. 什麼是java編譯器的優化級別?
- 26. Java編譯器是否有效地處理內聯字符串?
- 27. '編譯和鏈接'和'編譯'(用g ++)有什麼區別?
- 28. 是否有編譯爲機器代碼的C C++ C#編譯器
- 29. org.osgi。*的包導入是否有區別?
- 30. Ruby中的「!=」和「!〜」是否有區別?
順便說一句 - 我所知,主要是優化實際上是由JIT編譯器@EelLee JIT編譯器是Java中的唯一真正的編譯器完成的,而不是編譯器本身 –
。我不知道從源代碼到字節碼的轉換稱爲「編譯」的任何其他語言。 –
@MarkoTopolnik似乎被廣泛使用。我不知道爲什麼你認爲「編譯」只適用於最終結果是本機代碼的情況。 – Kayaman