前面的内容请看: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群里的朋友所说的那样,在云计算领域可能会大放光彩。
因为能力、精力和资源有限,此次比较测试并不完美,可能存在很多问题。欢迎有兴趣的朋友讨论并发表意见。