這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
這次我打算好好寫, 因為最近有點閑.
首先介紹兩種語言:
DLang
如果你不介意閱讀英文, 那麼DLang的官網有一份非常好的介紹, 簡單概括下就是
- C太古老了, 缺乏很多新的特性.
- C/C++太複雜了, 但是語言標準就有數百頁之多.
- C++中有很多常用的, 好的特性是通過標準庫實現的, 而非編譯器, 這樣無法做到最好的最佳化.
- D希望簡化開發, 降低複雜度, 但同時保留大多數好的特性.
- 作者希望這能成為C/C++的代替品.
對我來說, DLang意味著:
- 記憶體回收. DLang採用了多線程GC(有時間我會寫寫這個), 回收精度很高, 效能損耗卻非常小.
- C Style Syntax. C和D之間類似的代碼具有類似的功能.
- DMD + LDC. DMD是官方的後端, 而LDC則是基於LLVM的後端, 前端則都是相同的DMD Front End.
- 鬆散的特性集合. D擁有運算子多載, 泛型程式設計, RTTI, 內建複數支援等.
- 包管理系統. 包的名稱和匯入與所在檔案夾有直接關聯, 簡化了管理.
GoLang
我沒有找到關於Go語言設計哲學的官方文檔, Ken, Rox, Rob等人對於這門語言的討論和介紹散見於他們的部落格和群組裡.如果你有興趣瞭解這門語言, 官網上有一片洋洋洒洒的Spec,
我不太想四處拷貝整理出他們的設計思想, 在這裡只說說我看到的:
- C太古老, 太低級. C++太複雜.(Rob Pike討論Go語言發端時提到過), 因此需要一個具有現代特性, 複雜度低的語言.
- 這門語言有最小化的特性集合, 其他內容均有標準庫提供.
- 它具有類似C的文法, 能夠編譯成二進位代碼, 並且內建並發支援.
- 作者們希望這能成為C++的代替品.
對我來說, GoLang意味著:
- 記憶體回收. Go有記憶體回收, 至於更詳細的可以參看這裡.
- 開源.
- Pascal Feel C Style Syntax.
- 大量的文法糖.
可以看到, 二者的目標都是替代C++, 目標都是簡化軟體開發. 不過二者的設計思想卻是截然相反.(*二者的目標在某種程度上不太一樣, 雖然Go號稱是泛用的語言, 但它依然主要是面向網路編程)很久之前Group上有一篇討論DvsGo的文章, 可以作為參考.
Language Performance
對我來說, 運行速度是最重要的內容之一, 因此首先來看一組對比.所有的語言採用完全相同的代碼, 沒有特別最佳化.三組測試分別是N體問題(測試數值計算速度), 素數(測試整數/邏輯處理), BT(測試記憶體效能). 其中Go沒有編譯選項.每個測試回合5次, 取最優. 左邊是時間, 右邊是記憶體.
可以看到D-DMD和Go表現相近. 不過基於LLVM的ldc表現相對好些.(*go沒有基於llvm的版本)但二者表現都沒法與GCC相比. 記憶體使用量上則是FreePascal佔優, 這是來自它標準庫的特別處理方法.不過根據前面提到的909Bug, Go在32位系統下表現會更差.
Language Style
代碼是K-Means, 二者用了類似的演算法.
GoLang:
DLang:
文法很大程度上基於個人感受, 不過可以看到在普通的環境下並沒有什麼大的差別. 不過問題在與C的互動上:
首先看看Go下使用GSL的API:
不但需要引入unsafe包, 並且需要用大量的類型轉換(注意第32行). 這點非常容易出錯.
D上則好了很多, 只需要簡單的聲明, 變數是可以互換的. 下面是一個lapack的聲明.
入門/深入閱讀資料
D只有兩本書比較權威: <D Programming Language> <D Spec>剩下的只有D的官網和論壇. 不過好在<DPL>一書是D語言作者編寫的, 內容也非常全面.
Go語言最近有了不少書, 包括中文的<Go語言, 雲動力>, <Go語言編程>等, 英文版有<The Way to Go>, <Go Programming>等.不過大部分的品質都不高, 僅僅停留在介紹文法, 介紹標準庫, 貼幾個樣本程式而已. 只能作為入門讀物.
最後, 說個我
自己的小例子.前陣子需要做文字聚類, 於是隨手選了Andrew Ng教授01年的文章實現了下, 最開始用的是Go.最後整個工程超過了1萬行. 分成8個包, 每個包平均由5個檔案組成.測試資料用了1000單詞, 2萬文章.
結果已耗用時間超過了48小時. 記憶體佔用高達1.24GB.(編譯器: Go1.0.2)隨後我用D重寫了整個工程, 最終代碼只有4000行. 在同樣的機器, 同樣的資料上做了測試,
只花費了25分鐘. 記憶體佔用只有124MB.(編譯器: DMD)二者均沒有使用並發. 但都很容易實現. Go裡可以簡單地 go func來實現. D裡可以用range和parallelism.map/reduce.可以看到, 相比於測試裡的表現, 實際應用裡二者差距還是非常大的. 在更大的資料上(12萬文章), Go消耗了接近4GB記憶體,而D則只有數百兆.