這是個小規模的基準測試,涉及9種現代語言或其變種:Java 1.3.1, Java 1.4.2,使用gcc 3.3.1編譯的C,Python 2.3.2,使用 Psyco 1.1.1 編譯的Python,四種Visual Studio .NET 2003支持的語言:Visual Basic, Visual C#, Visual C++和Visual J#。
這個Benchmark使用了各種數據類型測試數學和三角函數,簡單的文件I/O。 所有測試都在運行Windows XP的Pentium 4機器上完成。

促使Christopher做這個測試的理由有5個:
第
一,他很好奇Java 1.4.2--最新的官方Java發布版--和Microsoft的.NET 2003
系列語言誰的性能更好。 Java和.NET
語言都是semi-compiled或者說semi-interpreted的。 源碼都被編譯成中間代碼,然後與解釋器或者JIT編譯器一同運行。 對
Java來說,中間代碼就是字節碼,解釋器/編譯器就是Java虛擬機JVM;.NET世界裡的源碼被編譯成Microsoft中間語言MSIL,運行
在.NET公共語言運行時引擎上。
除了擁有令Java廣受歡迎的特性比如自動資源管理,垃圾收集和類型安全外,.NET還有些新特性,比如跨語言調試,簡易的GUI設計和極為直白的應用部
署方法。 不過,這些特性會帶來性能損失嗎? 在對其編程模式增加了複雜的層次結構後,Microsoft是否放棄了其對Java的速度優勢?
Christopher的想法是,Microsoft提供的J#是一個Java 1.1.4規範的Java實現,似乎可以用這玩意來和Java比照,結果應該可以反映出SUN和Microsoft的運行時系統開銷。
第 二,Microsoft宣稱同樣的程式,用任何一種.NET語言編寫然後編譯到相同的MSIL後,最終能以相同的速度運行--這個說法確實很誘 人,Christopher當然想檢驗一下。 這個基準測試的代碼相當簡單,這麼做才能保證各種.NET語言編寫的例程在功能上是同等的。 這四種語言是 不是真的速度相同呢?
第三,想看看Java或者.NET到底比完全編譯的C慢多少。 Christopher開始嘗試了把CLR從 Visual C++ benchmark中剝離出來--用#pragma unmanaged預處理指令關閉託管特性,不過沒有成功,性能未見任何改善。之後Christopher把VC程序用gcc重新編譯,以便讓C能真正的 享受本地代碼,不託管,不依賴CLR的好處。
第四,看看semi-compiled語言和完全解釋語言的差別,後者的代表是Python,Perl和PHP。 現在有種觀點是隨著硬件速度越來越快,價格越來越便宜,我們會發現編譯型語言的速度優勢會大大無用。
最後,Christopher想看看Java前後不同版本之間的差別--這壞小子。 SUN關於1.4.2性能提升的大牛皮早就吹出來了,所以咱們這次也測測Java 1.3.1到底和1.4.2差別有多大。
設 計良好的測試案例簡直是fiendishly difficult。 Christopher只測試了數學運算(32位整數算術運算,64位整數算術,64位浮點算術,64位三角運算),之後是順序訪 問的文件I/O。 測試並不復雜,沒有涉及字符串處理,圖形,對象創建與管理(對面向對象語言),複雜數據結構,網絡訪問,數據庫訪問。 測試雖簡單,不 過能給出各種語言效率到底如何的大致印象。
32位整數運算:
使用32位循環計數器和32位整數操作數,循環從1到100萬。 忽略餘數。
1 – 1 + 2 * 3 / 4 – 5 + 6 * 7 / 8 – … – 999,999,997 + 999,999,998 * 999,999,999 / 1,000,000,000
64位整數運算:
算法同上,換為使用64位循環計數器和操作數。 循環從100億到110億。
64位浮點算術:
和64位整數算術算法相同,不過使用64位浮點循環計數器和操作數,不忽略餘數。
64位浮點三角函數:
使用64位浮點循環計數器,計算從1到1千萬的所有值的sin,cos,tg,基於10的對數和平方根。
I/O:
寫100萬行80個字符的數據到文本文件,然後讀回內存。
編譯及優化等選項:
Java 1.3.1:javac -g:none -O編譯,java -hotspot 運行。
Java 1.4.2:javac -g:none 編譯,java -server 運行。
C:gcc -march=pentium4 -msse2 -mfpmath=sse -O3 -s -mno-cygwin 編譯。
Python with and without Psyco:無優化。 python -O只能加快加載,對運行無用。
Visual Basic:使用Release配置,大開optimized,關閉integer overflow checks。
Visual C#:release,打開optimize code。
Visual C++:release,打開whole program optimization,優化為maximize
speed,打開global optimizations,enable intrinsic functions,設置size or
speed為favor fast code,設置omit frame pointers為yes,設置optimize for
processor為Pentium 4 and above,設置buffer security check為no,設置enable
enhanced instruction set為SIMD2,設置optimize for Windows98為no。
Visual J#:release,打開optimize code,關閉generate debugging information。
這裡是 測試代碼 。 Java
1.3.1, Java 1.4.2和Visual J#使用的是相同代碼。 Visual C++和gcc
C使用幾乎相同代碼。 C程序在Cygwin下用gcc編譯。Psyco:增加import
psyco和psyco.full()到Python代碼頭部。 四個Microsoft語言的測試在Microsoft Visual Studio
.NET 2003下完成。
Java的log() 函數使用e為底算自然對數,其他語言都用10為底算對數。很奇怪Java沒有基於10的log函數,這可能會影響性能。
執行每個測試前,Christopher都整理了硬盤,重啟機器,並關閉了不需要的後台服務。 每個測試都運行了至少3遍,選用了最好結果。 啟動時間未計算在內。 測試的硬件環境是:
Type: Dell Latitude C640 Notebook
CPU:
Pentium 4-M 2GHz
RAM: 768MB
Hard Disk: IBM Travelstar 20GB/4500RPM
Video: Radeon Mobility 7500/32MB
OS: Windows XP Pro SP 1
File System: NTFS
結果:
Python/Psyco 結果剔除在外--因為數字太大^_^
單位:秒
數值越小越優秀。
| int math | long math | double math | trig | I/O | TOTAL | |
| Visual C++ | 9.6 | 18.8 | 6.4 | 3.5 | 10.5 | 48.8 |
| Visual C# | 9.7 | 23.9 | 17.7 | 4.1 | 9.9 | 65.3 |
| gcc C | 9.8 | 28.8 | 9.5 | 14.9 | 10.0 | 73.0 |
| Visual Basic | 9.8 | 23.7 | 17.7 | 4.1 | 30.7 | 85.9 |
| Visual J# | 9.6 | 23.9 | 17.5 | 4.2 | 35.1 | 90.4 |
| Java 1.3.1 | 14.5 | 29.6 | 19.0 | 22.1 | 12.3 | 97.6 |
| Java 1.4.2 | 9.3 | 20.2 | 6.5 | 57.1 | 10.1 | 103.1 |
| Python/Psyco | 29.7 | 615.4 | 100.4 | 13.1 | 10.5 | 769.1 |
| Python | 322.4 | 891.9 | 405.7 | 47.1 | 11.9 | 1679.0 |
點擊產看全尺寸圖表
740)this.width=740″ border=undefined>
分析:
第一,Java(至少1.4.2的Java)和.NET
2003系列語言比,在大多數測試中表現都很不錯。 除了三角計算,Java事實上和VC--Microsoft最快的語言--一樣快。 不過Java的
三角也太差了,連解釋執行的Python都不如。 讓人迷惑的是1.3.1的三角表現不錯。
第二,Microsoft聲稱的所有的4種.NET語言都編譯成MSIL似乎確有其事--至少對數學函數。 整數算術運算的結果4種語言幾乎相同。 長整
數,雙精度和三角結果:VC#,VB和VJ#相同,不過C++編譯器輸出了令人印象深刻的快速代碼。 可能C++能更好地利用Pentium
4的SSE2 SIMD擴展完成算術和三角運算--僅是猜測。 I/O測試兩極分化,Visual Basic 和Visual
J#顯然在利用I/O例程上效率比VC#和VC低。 很明顯,功能相同的代碼並沒有編譯成相同的MSIL代碼。
第三,Java 1.4.2和gcc C一樣優秀乃至更好--除了三角計算外。 這是這次測試裡最讓人吃驚的地方。 通常合乎大家邏輯的猜測是在JVM中運行字節碼會帶來某種性能損失--和本地機器碼比較。 在這次測試中,這個推測顯然不知為什麼不成立。
第四,全解釋執行的Python,和推測的一樣,比任何全編譯或半編譯的語言都慢很多--又是甚至有1/60的差距。 不過I/O性能
上,Python和最快的語言也屬於同一陣營,而且比VB和VJ#快。 Psyco編譯器能為Python創造奇蹟,為數學和三角計算減少了10%到
70%的時間--和未經Psyco編譯的Python比。 和把Psyco 包含到Python中的簡單相比,這個性能提升是多麼驚人啊。
第五,Java 1.4.2比Java 1.3.1在算術上快很多。 不過,前面提過,三角運算則落後了。 Christopher
猜測1.4.2中應該還有不同的,更有效地調用三角函數的方法。 還有一種可能是1.4.2更注意精確而不是速度,所以新函數更準確但是速度更慢。
限會員,要發表迴響,請先登入

