Java与F#的并行程序处理对比

  Azul System的Cliff Click博士是多核心JVM系统方面的专家,之前发表了一篇博文,首先比较了Java与C语言和C++的性能表现,但同时也讨论了C#和.NET。以下三个Cliffs博士的评论让人十分感兴趣:

  在标题”Places where C/C++ beats Java for obvious reasons”下:

  “值类型,例如复杂类型,在Java中需要一个类来支持”

  ”Value Types, such as a ‘Complex’ type require a full object in Java.” – Dr Cliff Click

  Cliff忘记提及的是.NET同样提供值对象和比复数更加引人注意的humble hash table。

  考虑一下以10,000,000个整数/单精度浮点数 填充hash表,这个任务可以使用Java来完成,如下:

  

    packagehashtablebenchmark; importjava.util.HashMap; publicclassMain{ publicstaticvoidmain(String[]args){ intn=10000000; for(intj=0;j<10;++j){ longstartTime=System.currentTimeMillis(); HashMaphashtable=newHashMap(n); for(inti=1;i<=n;++i){ hashtable.put(i,1.0f/i); } System.out.println(“m[100]=”+hashtable.get(100)); longtime=System.currentTimeMillis()-startTime; System.out.println(“Took:”+time/1e3+”s”); } } }

  同样的程序在F#中不仅仅代码更短并且速度要快上17倍:

  

    letn=10000000letm=System.Collections.Generic.Dictionary(n) fori=1tondom.[i]<-1.0f/float32i printf”m[100]=%f\n”m.[100]

  特别值得提及的是,Java初始化花费6.967s、稳态花费5.733s,而F#只用了0.414s。

  实际上,F#通过这个测试后我们便想给它更大的工作量,而在这台4GB内存的机器上,Java不可能再做更多了。

  在别处的评论,Cliff也这样写到Java:

  “有非常好的多线程支持,并行程序设计在Java中很容易实现”

  ”Very Good Multi-Threading Support. Parallel programming is just easier in Java.” – Dr Cliff Click

  之后又有:

  “并非我如此关注C#而是…我认为JIT编码处理基本上比Java要慢”

  ”Not that I track C# all that closely but… I believe the JIT produces substantially slower code than Java” – Dr Cliff Click

  允许我们在其他方面来证明,Computer Language Shootout软包含了一个格式良好的spectral-norm测试,最快的Java解决方案是一个173行的并行程序。其实现用F#来写只需要24行代码:

  

    letAij=1.0/float((i+j)*(i+j+1)/2+i+1) letinlinemulA(u:_[])(v:_[])= System.Threading.Tasks.Parallel.For(0,v.Length,funi-> letmutablevi=0.0forj=0tov.Length-1dovi<-vi+Aij*u.[j] v.[i]<-vi)|>ignore letAtAuuv= letw=Array.create(Array.lengthu)0.0mul(funij->Aij)uw mul(funij->Aji)wv doletn=5500letu,v=Array.createn1.0,Array.createn0.0fori=0to9doAtAuuv AtAuvu letu,v=vectoru,vectorv printf”%0.9f\n”(sqrt(Vector.dotuv/Vector.dotvv))

  在Java代码中,大量的代码都是用来实现并行化。与之相反的是,F#在处理并行化上只用了两行代码。可见,并行程序设计在Java中可不是那么easy。

  Java串行程序初始花费了12.722s稳态花费12.299s,而冷启动的F#只用了12.18s。在8核 2xE5405 2.0GHz Xeon的机器上,Java并行程序初始化花费1.839s稳态花费1.820s,而冷启动的F#并行程序只用了1.60s。事实证明,Java在每一个测试中都表明CLR的JIT并不是“处理基本上比Java更慢”

  最后,Cliff并没有提到其他两个设计上(Java性能)的不足。首先,Java的泛型代码导致性能大幅下降,由于它使用了许多不必要的装箱操作。其次,JVM栈缺少尾部递归支持,这不仅仅对这个函数式编程的年代带来越来越多的障碍,而且唯一的一般解决方案也比需要的慢上10倍。

那段岁月,无论从何种角度读你,你都完美无缺,

Java与F#的并行程序处理对比

相关文章:

你感兴趣的文章:

标签云: