2008-12-31 21 views
11

我想知道是什麼讓主編譯器(sun編譯的javac)如此快速地編譯?是什麼讓Java編譯器如此之快?

..以及來自Microsoft的C#.NET編譯器。

我將它們與C++編譯器(如G ++)比較,所以也許我的問題應該是,是什麼讓C++編譯器很慢:)

+0

你在比較什麼?從源代碼編譯應用程序所需的時間或運行時間性能? – 2008-12-31 13:46:25

+2

用一些例子可能會更有趣。一些測量與定時+多行代碼。 – 2008-12-31 13:50:12

+0

我正在比較編譯時間,而不是運行時間。 – Lawand 2008-12-31 13:56:55

回答

16

這個問題是在這一個很好的回答:Why does C++ compilation take so long?(正如jalf在評論部分指出的)

基本上它是C++的缺失模塊概念,以及由編譯器進行的積極優化。

2

C++編譯器必須反覆編譯所有的頭文件和有很多,所以這是一個減緩它的一件事。

+0

人們可以使用預先標題來加快速度。 http://en.wikipedia.org/wiki/Precompiled_header – 2008-12-31 13:52:36

6

我認爲最困難的部分不是編譯頭文件(除非它們真的很大,但在這種情況下可以使用預編譯頭)。最糟糕的部分總是這樣一個事實,即C++的語法對上下文非常敏感。儘管我喜歡C++,但對於任何需要編寫C++解析器的人都感到抱歉。

+6

不要擔心 - 這是世界上約10-20人:) – MSalters 2009-01-02 14:11:45

1

我認爲它的一部分是語言的複雜性。 C++是令人難以置信的可變的,能夠覆蓋幾乎任何操作符或語法片段(如覆蓋()運算符)。這意味着編譯器必須做更多的工作才能確定實際運行哪些操作,即使對於簡單的事情也是如此。 Java和C#沒有這個問題,因爲語法是固定的,而且它們通常更容易解析。

2

編譯時更耗時的任務之一是代碼優化。

在進行編譯時,Javac對代碼做了很少的優化。當運行應用程序時,優化由JVM完成。

編譯後的C/C++需要進行優化,因爲優化編譯的機器代碼很困難。

2

你就在你的最後一句明白了:這不是Java或C#這是快速編譯,這是C++是編譯,由於其複雜的語法和功能非常慢,最重要的templates

2

如果您認爲javac是快速嘗試Jikes ....(請參閱http://jikes.sourceforge.net/) 這是一個用C++編寫的Java編譯器。不幸的是,他們沒有跟上最新的Java編譯器規範,但如果你想快速看到這是它。

託尼

5

有一對夫婦的東西,讓C++編譯器比對Java/C#慢。語法要複雜得多,通用編程支持在C++中更強大,但同時編譯成本更高。包含文件的方式與導入模塊的方式不同。

的Inclussion頭文件

首先,當你包括C++中的文件中的文件的內容(.H通常)在當前編譯單元被注入(include防範避免再注入相同的頭兩次) ,這是傳遞性的。也就是說,如果你包含頭文件a.h,這個頭文件包含b.h,你的編譯單元將包含所有的代碼。h和b.h中的所有代碼。 Java(或C#,我將討論Java,但它們在這方面類似)沒有包含文件,它們依賴於編譯所使用的類的二進制文件。這意味着,無論何時編譯使用b.java中定義的對象B的a.java,它都會檢查二進制b.class,它不需要深入檢查B的依賴關係,因此它可以更早地切斷進程(只有一個級別的檢查)。

與此同時,包括文件只包括語言定義,並且處理它需要時間。當Java/C#編譯器讀取二進制文件時,它具有相同的信息,但已經由生成它的編譯步驟處理。

最後,在C/C++中包含更多的文件,同時處理這些文件比處理二進制模塊更加昂貴。

模板

模板是用自己的方式特殊。它們可以預編譯,但通常不會(出於一系列原因)。這意味着在所有使用std :: vector的編譯單元中,使用的整套矢量方法(未使用的模板方法無法編譯)將被處理,編譯器會生成二進制代碼。在稍後的步驟中,在鏈接期間,同一方法的冗餘定義將會丟失,但在編譯期間,它們必須被處理。

在Java中對泛型的支持在很多方面受到更多限制。最後,例如,只有一個Vector類二進制文件,並且只要編譯器在Java中看到Vector,它在委託給真實的Vector實現(存儲普通對象)之前生成類型檢查代碼,這不是通用的。編譯器確實提供了類型保證,但不針對每種類型編譯Vector。

在C#中,它再次與衆不同。 C#對泛型的支持比Java更加複雜,並且最終泛型類與普通類不同,但無論如何它們只能編譯一次,因爲二進制格式具有所有必需的信息。

3

由於它們做了一些完全不同的事情,C++編譯器會生成優化的本地代碼,而C#,VB .Net和Java編譯器會產生中間語言,而不是當您第一次執行應用程序時會轉化爲本機代碼,這就是爲什麼您變慢首次執行應用程序時,會在Java中加載應用程序等。

C++編譯器必須在執行應用程序時進行JITed語言優化的完全優化。

有人會爭辯說,如果你想要正確地加載應用程序,你必須測量C++編譯時間= Java編譯時間+ JITing的時間,但我認爲這不是正確和公平的,因爲你正在比較本地語言JITed,否則橙子蘋果。

1

比較像Java這樣的字節碼語言和C++等原生編譯語言有點困難。 Delphi和C++比較好,Delphi的編譯速度要快得多。由於這與優化或字節碼無關,它必須歸因於語言語法的差異以及包含與模塊/單元的相對性能。

0

Java編譯器是否很快?

Java到類的翻譯應該是非常快的,因爲它只是一個帶有語法檢查的美化zip,因此與真正的編譯器相比,它是在進行優化和目標代碼生成,從Java到類的「翻譯」是微不足道的。

與比較小的程序「hello world」和比較GCC(C/C++/Ada)並發現javac慢30倍,運行時會更糟?

相關問題