標籤:

為什麼 C# 的語法特性並不比 C++ 簡單,但編譯速度卻比C++快那麼多?

感覺可能跟C#是編譯成IL位元組碼有關,但是應該還有別的原因


C#比C++語法簡單得多好嗎。也不需要那麼多代碼在頭文件。


前面幾位答主已經提到很多了,我這邊再提一個蛋疼的東西:模板!!!

C++98就引入了模板,然後整個STL都是模板。而模板又分為普通的模板和模板元編程。

首先,模板很難預編譯。

實際上根據標準,模板是不預編譯,直接從源文件導入,在工程編譯的時候編譯的。因為模板的原理簡單來說是改進的、更加安全的、更加強大的宏機制。比如所有接受數據類型名為參數的模板,幾乎必須是在編譯的時候才能確定到底是啥,然後直接展開到源代碼裡面去

舉個例子,寫個簡單的max函數:

template &
tname max(tname a, tname b){
return a&>b?a:b;
}

如果你這個max函數用在了double和int兩種類型上,那麼實際上就會編譯出兩個max。而整個STL就是一大堆模板混來混去,你用一個vector,你至少就帶了一個less。何況還有優化的部分,這裡的時間開銷都在編譯時間。C#我並不是很了解,據說更多用泛型,替換在運行時執行,這顯然大大減少了編譯時間的開銷。

模板元編程就更喪病了,最大的用途就是直接把運行時的一些可能重複使用,每次結果又一定一樣的代碼,乾脆在編譯時做掉。比如有個科學計算程序需要算階乘,那麼利用模板元編程就可以很容易地提前算好,運行時就沒有這個計算的開銷了。作為代價……編譯的時間就要用力算了。基本上用了模板元編程的代碼都是編譯得慢得吐血,不然怎麼能在運行的時候快呢?

至於parse幾遍、優化什麼的其他答主都提到。有些語法特性特別耗費編譯時間,如果這些特性恰好是你用得最多的特性,那麼整體來看編譯時間的開銷自然就很大了。而模板恰好是用的多卻編譯得慢的C++語法特性。不過慢怕啥呢?我們不是多了好多喝下午茶的美好時光嗎?(* ̄︶ ̄)y

參考資料:

【1】C++ 模板和 C# 泛型之間的區別(C# 編程指南)


顯然這個不能從語法特性上來看,你想C的編譯速度也這麼慢。

主要原因,一個是工程的組織方式導致的,C/C++通過include的方式來分離編譯編譯單元,結果是每個引用了幾個標準庫的.cpp文件宏展開後輕鬆上萬行,Parse的開銷就比別的語言高。

另一個就是因為是AOT,優化器喪心病狂,不像C#,很多優化都是運行時才去做的


因為C#沒有偏特化,

不用兼容C的特性.文法比C++規範多了,方便解析

下面來源匿名用戶的提醒

另一方面,C++的include方式拖慢編譯速度,include簡單粗暴的文本插入頭文件全部內容.隨便一個小項目,全部include展開和宏展開輕輕鬆鬆10W行.要編譯的代碼太多了- -編譯速度就慢了.

C++沒有運行時.全部優化都是編譯時做.編譯期優化喪心病狂.parse一遍又一遍....

每次用C#那種秒啟動的感覺想到C++都是淚流滿面


C#編譯過程幾乎不用做文本預處理,語法簡單一個數量級,不用鏈接,而且最重要的是不用做(編譯器)後端優化


C++試試用clang++,預編譯頭文件,輸出位元組碼,快多了。

頭文件的負擔倒不在include重複,現在的編譯器對頭文件處理做過性能優化。麻煩的是所有符號要進object,只能老老實實全部處理一遍。

後端優化是比較大的一塊,C++負擔更大,因為不能扔給鏈接器(如果需要object二進位兼容)和運行時。

當然估計還是沒C#快,還得考慮元編程、重載,以及一大堆詭異的語法(比如C風格cast)和語義(比如繼承類成員類型規則)的負擔。

排除這些,最後還是沒C#快,因為Anders。


看stack overflow的高票答案,感覺總結的不錯:

compiler construction


推薦閱讀:

學C++真的需要看那麼多書嗎?
既然建議盡量避免使用goto語句為何C++還要支持goto呢?
c++ ,如何按照不同的要求調用標準庫sort函數排序?
在C#中,如何實現跟native dll 中途的線程間通信?
學C#需要學好C++么?

TAG:C | C# | 編譯原理 |