前面的內容請看:Java、Scala和Go語言多線程併發對比測試。 相關的代碼下載:http://qinhui99.itpub.net/resource/2570/31876
測試結果和結論html
AMD 雙核 2.8G ,4G內存 winxpjava
java+conc java+AKKA1.3 java+AKKA2.0 Scala+AKKA1.3 Scala+AKKA2.0 Go+goroutine程序員
1-N 單位:秒 算法
1000000 0.64 1.14 0.63 1.05 0.65 0.617編程
2000000 1.71 2.08 1.58 2.05 1.68 1.63windows
3000000 3.05 3.28 2.79 3.3 2.96 2.91多線程
5000000 6.32 6.18 5.75 6.367 6.1 6.04併發
10000000 17.14 15.85 15.8 16.5 16.6 16.35框架
12000000 22.4 20.48 20.2 21.32 21.48 21.3編程語言
(因爲AMD硬件平臺性能很爛,測試時間較長,因此只測試到12000000)
INETL 平臺 酷睿雙核2.4G ,4G內存 winxp
java+concurrent java+AKKA1.3 java+AKKA2.0 Scala+ AKKA1.3 Scala+ AKKA2.0 Go+goroutine
1-N 單位:秒
1000000 0.209 0.87 0.235 0.73 0.219 0.28
2000000 0.53 1.12 0.48 0.98 0.485 0.54
5000000 1.93 2.19 1.55 2.08 1.61 1.65
10000000 4.93 4.62 4.09 4.57 4.1 4.18
20000000 13.25 11.14 10.95 11.13 10.92 10.98
30000000 23.24 19.37 19.13 19.25 19.35 19.39
測試真是又費時間又枯燥的事情。在兩個硬件平臺測試了以後,還有一個蘋果系統的沒有時間進行測試,先放着,等之後再補上吧。
性能測試結果說明:
一、 爲了公平起見,各個組合的算法都是採用給多線程傳遞不變的參數,避免使用同步鎖,儘可能減小由於實現語言的不一樣而影響性能的因素。
二、 性能表現最好的前3個分別是:java+AKKA2.0,Scala+AKKA2.0,Go+goroutine。這3個組合的多線程併發計算指標比較接近。儘管在測試前,對Go語言報了很大指望,覺得Go會是測試的冠軍,但事實證實,對這個CPU密集運算的多線程併發測試案例來講,Go並不佔優點,甚至不如java+AKKA2.0組合。這也證實了AKKA這個高性能併發運算框架果真很優異。不瞭解AKKA2.0的朋友,請訪問:http://www.gtan.com/akka_doc/index.html。
三、 性能表現最常的是java+concurrent。當計算量小的時候,例如,1000000如下的時候,java+concurrent表現還不錯。但計算量不斷增大的時候,java+concurrent開始表現糟糕。在10000000以上的時候,java+concurrent表現更加糟糕。表現糟糕的緣由多是由於用到了 concurrent 的ExecutorService和Future。 Future實際上是一種阻塞線程模式,因此性能並非最佳。有時間讀讀AKKA2.0的源代碼,也許能找到一些改進性能的參考辦法。
四、 性能表現通常的是java+AKKA1.3和Scala+AKKA1.3。它們和AKKA2.0版本的最大差別是,它們採用的是發送並等待返回消息的阻塞模式,而AKKA2.0版本則採用發送就無論了的無阻塞模式。事實證實,阻塞模式比無阻塞模式性能要差很多。此外,儘管AKKA1.3的阻塞模式性能很差,但在大計算量的狀況下表現仍然不錯,和Go語言差很少,比java+concurrent要好。
五、 在運行java程序的時候,都加上了-server參數。而對於Scala和Go,我不瞭解該怎麼優化,因此都只是使用Scala和Go普通的運行命令來啓動程序。例如,
java -server org.aos.concurrent.samples.ConcurrentPrimeFinder 1000000 10 100
scala com.agiledeveloper.pcj.Primes 1000000 100
test_prime.exe -n=1000000 -workers=100
編程的難易程度測試結果說明:
一、 因爲本人有多年的JAVA編程經驗,因此java+concurrent組合是編碼花費時間最少的。
二、 對於Scala和Go語言,本人學習的時間都差很少,3個星期左右。因爲Scala和JAVA平臺的互通性,也因爲Scala平臺的成熟和易用(開發工具和語法比Go好很多),因此開發Scala版本比Go版本所花費的時間要少。
三、 Scala+AKKA1.3比Scala+AKKA2.0版本更容易開發。由於Scala+AKKA1.3的阻塞模式容易理解,代碼量也少。但阻塞模式在計算量比較大的時候,容易報timeout異常。須要增長一個akka.conf文件來定義更長的阻塞等待時間。對於Scala+AKKA2.0,AKKA官方提供了一個無阻塞模式的參考例子,採用master+worker+listener對象組合。Master分發多份工做給多個worker去計算, worker計算完後,分別把各自計算結果發回給master來彙總,最終,master把彙總結果發送給listener,並輸出結果。爲了使用這種對象組合,致使Scala+AKKA2.0版本的編碼要比Scala+AKKA1.3版本複雜,花費的時間也相應要多些。另外,因爲AKKA2.0採用無阻塞的模式,因此測試中沒有出現過因爲計算量大而出現的timeout問題。
四、 從Scala轉到Java版本,確實有些困難,但幸虧兩個平臺是互通的,而且有參考的例子,因此轉過來也不是太困難。和Scala版本同樣的,java+AKKA1.3版本比java+AKKA2.0版本要容易寫些,也存在着阻塞模式的timeout問題。
五、 Go語言版本,因爲和Java平臺不互通,並且差別極大,編碼花費時間最多。Go語言從Scala和Python等語言裏獲取了許多有益的東西,語法比較簡潔,編譯速度快,佔用內存少,並且以goroutine的方式很方便地寫出支持多線程併發計算的程序,確實頗有發展前景。(在用過Scala和Go語言以後,真的很討厭JAVA裏面冗長的代碼,特別是該死的分號‘;’)
但Go語言的缺陷也挺多的。這裏就列幾個測試所發現的狀況:1)語言比較新,懂的人很少。這意味着學習成本和用人成本比較高;2)開發平臺不成熟,在windows下安裝配置Go的開發環境,本人的經歷很痛苦。有一種當年用EditPlus寫JAVA代碼的感受,很不爽。3)強類型轉換,很煩人。爲了使用math.Sqrt,竟然逼我寫了一段從float64轉int的代碼。在Java和Scala從未出現這樣的狀況。算是明白了,Go所謂的編譯快其實就是程序員本身多付出點代價來照看代碼。4)goroutine容易出現deadlock死鎖現象。死鎖的緣由不少,讓初學者頭痛。
測試的最終結論:
綜合性能測試和編碼難易程度測試結果,本人從作項目的角度得出幾點結論:
一、 對於Java程序員,若是沒有強制性的必要,不須要轉到Scala和Go語言,由於Java+AKKA2.0足夠好用了,足以應付多線程高併發應用。
二、 對於Java程序員,若是程序應用於通常的多線程應用,而且性能要求不高,java的concurrent包也夠用了。
三、 對於Java程序員,若是想讓項目的代碼量減小一半,學習成本不過高,性能也有保障的話,Scala語言是很是好的選擇。
四、 對於Java程序員,若是項目時間有限,想要用Go語言來實現項目,那基本死路一條。
五、 對於Go語言的將來,也許如Go編程語言QQ羣裏的朋友所說的那樣,在雲計算領域可能會大放光彩。
因爲能力、精力和資源有限,此次比較測試並不完美,可能存在很多問題。歡迎有興趣的朋友討論並發表意見。