作家
登录

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

作者: 来源: 2012-06-12 16:31:24 阅读 我要评论

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来完成,如下:

  1. package hashtablebenchmark;  
  2.  
  3. import java.util.HashMap;  
  4.  
  5. public class Main {  
  6.     public static void main(String[] args) {  
  7.         int n = 10000000;  
  8.  
  9.         for (int j=0; j<10; ++j) {  
  10.             long startTime = System.currentTimeMillis();  
  11.             HashMap hashtable = new HashMap(n);  
  12.  
  13.             for(int i=1; i<=n; ++i) {  
  14.                 hashtable.put(i, 1.0f / i);  
  15.             }  
  16.  
  17.             System.out.println("m[100] = " + hashtable.get(100));  
  18.             long time = System.currentTimeMillis() - startTime;  
  19.             System.out.println("Took: " + time / 1e3 + "s");  
  20.         }  
  21.     }  

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

  1. let n = 10000000 
  2. let m = System.Collections.Generic.Dictionary(n)  
  3. for i=1 to n do 
  4.   m.[i] <- 1.0f / float32 i  
  5. printf "m[100] = %fn" 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行代码:

  1. let A i j = 1.0 / float((i + j) * (i + j + 1) / 2 + i + 1)  
  2.  
  3. let inline mul A (u: _ []) (v: _ []) =  
  4.   System.Threading.Tasks.Parallel.For(0, v.Length, fun i ->  
  5.     let mutable vi = 0.0 
  6.     for j = 0 to v.Length - 1 do 
  7.       vi <- vi + A i j * u.[j]  
  8.     v.[i] <- vi) |> ignore  
  9.  
  10. let AtAu u v =  
  11.   let w = Array.create (Array.length u) 0.0 
  12.   mul (fun i j -> A i j) u w  
  13.   mul (fun i j -> A j i) w v  
  14.  
  15. do 
  16.   let n = 5500 
  17.   let u, v = Array.create n 1.0, Array.create n 0.0 
  18.   for i = 0 to 9 do 
  19.     AtAu u v  
  20.     AtAu v u  
  21.   let u, v = vector u, vector v  
  22.   printf "%0.9fn" (sqrt(Vector.dot u v / Vector.dot v v)) 

在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倍。

英文连接:http://fsharpnews.blogspot.com/2010/05/java-vs-f.html

原文链接:http://www.oschina.net/news/26564/java-vs-f

【编辑推荐】

  1. Java并发编程之同步互斥问题
  2. Java中String.format的用法
  3. 如何在Oracle中使用Java存储过程(详解)
  4. 关于读写锁算法的Java实现及思考
  5. 6个提高Java开发者效率的工具

  推荐阅读

  JDBC的封装类构建

在JAVA中JDBC的访问是比较麻烦的,为此可以使用封装的方法构建一个封装性较好的JDBC工具类,提高编程的可复用性。具体的想法是:可以生成一个类封装JDBC的connection和statement的构建,使用Property配置文件来保存J>>>详细阅读


本文标题:Java与F#的并行程序处理对比

地址:http://www.17bianji.com/kaifa2/Java/918.html

关键词: 探索发现

乐购科技部分新闻及文章转载自互联网,供读者交流和学习,若有涉及作者版权等问题请及时与我们联系,以便更正、删除或按规定办理。感谢所有提供资讯的网站,欢迎各类媒体与乐购科技进行文章共享合作。

网友点评
自媒体专栏

评论

热度

精彩导读
栏目ID=71的表不存在(操作类型=0)