主题:【倡议】Java SE 5.0和.NET 2.0擂台赛 -- Highway
现在,Java的一个重要版本终于面世了。不管怎么说,这是继Java 1.2之后的一个阶段性发展。而微软的.NET 2.0 Beta版本已经发布一段时间了。这两种技术在今后一段时间内将是应用程序市场开发的主流。希望大家就这两种技术提出自己的看法。不限形势,不限内容,大家尽可畅所欲言。比如两者性能有什么区别,功能有什么差异,Garbage Collection技术细节上有何异同,安装,发布的难度如何,和以往版本的兼容性如何等等。
总之一句话,希望大家踊跃发言!
俺一 样都不会...吼吼..
性能是一个语言的关键,所以我想做的第一件事就是比较一下Java SE 5.0和.NET 2.0 性能。
不过这并不是一个简单的问题。Benchmark program并不好写。因为这两种语言覆盖面极大,一个Benchmark program很难面面俱到。另外就是即使专注一点,也有很多细节要考虑。比如说I/O吧,你就可能要考虑读的性能,写的性能,大数据量连续读写的性能,小数据量高频率读写的性能,顺序Access问题,Random access问题,Text问题,Binary问题,诸如此类。
今天我从网上下载了一个别人以前写的Benchmark program。这个Benchmark program不是非常具有代表性,比如最重要的XML,Socket,Thread,database, serialization/deserialization等等都没有涉及,I/O和String的比较也太过简单了,有几处比较也不是所谓的Apple vs Apple(比如用Java的Vector比较C#的Arraylist).不过不管怎么说,这总是一个开头吧。
大家可以在这里得到程序源代码
有一点要说明一下,I/O部分有些问题,Java和.net得到的文件不一样大。我修改了两行,大致如:
String textLine = "abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefgh\r\n"; ... while (i++ < ioMax) { streamWriter.Write(textLine); } streamWriter.Close();
另外Java在测试中会出现Out of memory Exception.我只好给Java来了几个参数,以保证程序可以完成。具体是:java -Xmx500M Benchmark
这里是我的测试结果,在大多数情况下,.NET有优势,在个别测试上Java领先。由于Java和.NET的Exception设计不一样,所以这一项目差别特别大。另外Java的三角运算比.NET慢10倍左右,肯定也有些问题。我还没有仔细看。
[提示:原图站已失效]
另外,Generics的问题我将今后专门讨论!
那到它也是跟java一样的需拟机?
不是编译成binary?
Common Language Runtime.
编译的结果叫IL(Intermedia language),和bytecode类似,可以反编译得到源程序。运行的时候,由CLR的JIT将IL转化为机器代码。
这是我从网上找来的,本来应该以文摘的方式转载,但是西西河的文章标题长度限制使得它成为不可能,我只好把它附在内容里了。
.NET 2.0 and Java 1.5 for numerical computing
Going ahead with my numerical algorithms translation, I started to wonder if I was going to win something in performance. Is .NET 2.0 going to be faster than Java 1.5 for numerical computing? To find out, I downloaded the SciMark2 benchmark from the http://math.nist.gov site and I translated it to C# using Visual C# Express, at this point I didn't try to understand (let alone enhance) the code, only to get it working in C# (except a couple of obvious changes like using Array.CopyTo() to copy arrays). Anyway, these are the results I got with Java 1.5 Beta 2 in my portable (2.8 GHz Mobile Intel Pentium 4 CPU):
FFT (1024): 112.99822846954115
SOR (100x100): 378.42792716276983
Monte Carlo : 47.71337303709922
Sparse matmult (N=1000, nz=5000): 144.6072353535397
LU (100x100): 355.1855612455282
And these are the results I got with .NET 2.0 Beta 1:
Composite Score: 320.261977294581
FFT (1024): 225.063751509717
SOR (100x100): 395.271584950618
Monte Carlo : 18.592932017316
Sparse matmult (N=1000, nz=5000): 484.889267269725
LU (100x100): 477.492350725527
The results are in Mflops so Whidbey seems to be roughly 50% better than Tiger. Of course, these results are very preliminary and they will vary from machine to machine, so you can download the C# SciMark2 from http://www.logicstudio.net/Net2005/SciMark2.zip (the translation is awful right now and barely use C# idioms but, hey, it runs!) Give it a try and let me know how it goes.
Doing benchmarks is always dangerous, and doing it with betas even more so, so I run the benchmarks with Java 1.4.2_05 and got this:
Composite Score: 212.73680429939608
FFT (1024): 107.32467730480086
SOR (100x100): 376.06459421216255
Monte Carlo : 46.94569063386169
Sparse matmult (N=1000, nz=5000): 146.67860553090557
LU (100x100): 386.6704538152499
And with .NET 1.1.4322:
Composite Score: 336,152586167483
FFT (1024): 236,507205423729
SOR (100x100): 405,674738526316
Monte Carlo : 25,873449174941
Sparse matmult (N=1000, nz=5000): 476,624132235073
LU (100x100): 536,083405477354
For both platforms the production versions are better than the betas but note I run the tests in the same machine but with *different* Windows XP installations so don't jump into conclusions. In any case the difference between Java and .NET seems to be consistent.
一般来说IBM的虚拟机要比SUN的快上那么两三倍吧?
实在不行,SUN的虚拟机执行的时候用上-server模式也会加速的
看老兄上来就是“java -Xmx500M Benchmark”,心里就有气~~~~
摆明了是要SUN出洋相好看的嘛~~!
代表java用户鄙视一下
论坛推荐的都是Hotspot Sun JVM.
Server JVM在长时间运行的程序中会有一些性能提高,对于Client application,还是Client 参数比较好。这样程序载入快,Memory footprint小。
-Xmx500M不是一个好的例子。我只是想让Java能完成测试,不要出现Out of memory 问题。你可以自己试试看其他参数。
另外,如果你方便的话,可以帮我比较一下Sun JVM和IBM JVM有什么区别。
谢谢参与!!
接受了你克我服朋友的建议,使用了Java Server VM重新运行Java Program。令我吃惊的是在大多的测试中,Java有了非常大的提高(以前的Java VM两者区别不是很大,除非程序运行非常长的时间)。尤其是在Double和Long的运算上。总体上讲,Java和.NET这回是各有千秋。
另外,-Xmx256M比原来的小了一倍。这个参数的意识是Java VM可以使用256MB的heap size.缺省的64M没法完成String部分测试 。事实上原先使用的-Xmx500M对性能没有什么影响,我测试了几组,没发现什么大的区别。
[提示:原图站已失效]
按照常理,我应该直接评论Java 1.5和.Net 2.0这二者的优劣,可惜本人才疏学浅,觉得还是先熟悉一下Java 1.5和.Net 2.0,然后再展开Java 1.5和.Net 2.0之间的比较比较合适一些。同时为了不至于搞乱老轧同志的擂台赛主战场,我就另开一贴专门讨论Java 1.5的新特点作为擂台赛的分赛场,还请各位谅解。
串行化/反串行化就是所谓的Serializtion/De-serailization。在现在计算机技术中这是非常重要的一个环节。一个Object只有被串行化才可以在网络上传输,才可以保存到Disk或Database中。
串行化/反串行化根据用户的要求可能会非常的复杂(比如Versioning control, Thread status, Delegate等等东西),Java和.NET都有专门的文章介绍。今天我想测试的就是Out-of-Box性能,就是看看最基本的串行化/反串行化这两者性能如何。
最基础的串行化/反串行化程序员不用写程序,只要声明一下就可以了(详见Code)。我的实验非常简单,创建一些Object,然后放到ArrayList里去,一次性串行化/反串行化,看看其性能如何。
测试表明,.NET程序反应很快,对于小数据,少次数的调用性能很好(比Java好),但是一旦数据量变大,性能马上就开始下降。这时候Java会迎头赶上。在数据量达到3MB的时候,Java已经快出5倍以上,而在30MB的时候,会快出60倍。Java Server VM在数据量大的情况下比Client有较大优势。如果是非密集型的运算,Client VM可能更合适。
[提示:原图站已失效]
[提示:原图站已失效]
(50000*10用的时间太长了,没有等它完成)
下面是我的源程序,非常简单。大家可以随意修改,玩弄!!!
C# Code
#region Using directives using System; using System.Collections; using System.Text; using System.IO; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; #endregion namespace SerialTest { class Program { static void Main(string[] args) { new Program(); } public Program() { ArrayList a50 = prepareData(50); seDesTest(a50,1000); ArrayList a500 = prepareData(500); seDesTest(a500,100); ArrayList a5000 = prepareData(5000); seDesTest(a5000,10); ArrayList a50000 = prepareData(50000); seDesTest(a50000,1); //ArrayList a100000 = prepareData(100000); //seDesTest(a100000); } private ArrayList prepareData(int num) { long start = System.Environment.TickCount; ArrayList a = new ArrayList(); for(int i=0; i<num; i++) { MyObj aObj = new MyObj(DateTime.Now.ToString(),32,i*1000,DateTime.Now); a.Add(aObj); } long time = System.Environment.TickCount- start; //System.Console.WriteLine("Prepare time of " + num + " items: " + time+ " ms."); return a; } private void seDesTest(ArrayList a, int number) { long start = System.Environment.TickCount; ArrayList a1 = null; for (int i = 0; i < number; i++) { MemoryStream memStream = new MemoryStream(); IFormatter formatter = new BinaryFormatter(); formatter.Serialize(memStream, a); byte[] data = memStream.ToArray(); memStream = new MemoryStream(data); a1 = (ArrayList)formatter.Deserialize(memStream); } long time = System.Environment.TickCount - start; if(a1.Count != a.Count) { System.Console.WriteLine("Error happend, Invalid test!!!"); return; } else { System.Console.WriteLine("Serialization and Deserialization of " + a.Count.ToString() + "*" + number.ToString() + " items take:" + time + " ms."); //System.Console.WriteLine("Last Object: " + a1[a1.Count - 1].ToString()); } } } [Serializable] public class MyObj { private static readonly String NEWLINE = "\r\n"; private String m_name; private int m_age; private double m_salary; private DateTime m_hireDate; /** Creates a new instance of MyObj */ public MyObj(String name, int age, double salary, DateTime hireDate) { m_name = name; m_age = age; m_salary = salary; m_hireDate = hireDate; } public MyObj() { } public override String ToString() { StringBuilder sb = new StringBuilder(); sb.Append("Name: " + m_name + NEWLINE); sb.Append("Age: " + m_age + NEWLINE); sb.Append("Salary: " + m_salary + NEWLINE); sb.Append("Hire Date: " + m_hireDate.ToString()); return sb.ToString(); } } }
Java Code
import java.util.*; import java.io.*; public class Main { public Main() throws Exception{ ArrayList a50 = prepareData(50); seDesTest(a50,1000); ArrayList a500 = prepareData(500); seDesTest(a500,100); ArrayList a5000 = prepareData(5000); seDesTest(a5000,10); ArrayList a50000 = prepareData(50000); seDesTest(a50000,1); seDesTest(a50000,10); //ArrayList a100000 = prepareData(100000); //seDesTest(a100000,1); } private ArrayList prepareData(int num){ long start = System.currentTimeMillis(); ArrayList a = new ArrayList(); for(int i=0; i<num; i++) { MyObj aObj = new MyObj(new Date().toString(),32,i*1000,new Date()); a.add(aObj); } long time = System.currentTimeMillis()-start; //System.out.println("Prepare time of " + num + " items: " + time+ " ms."); return a; } private void seDesTest(ArrayList a, int number)throws Exception{ long start = System.currentTimeMillis(); ArrayList a1 = null; for(int i=0; i<number; i++){ ByteArrayOutputStream bout = new java.io.ByteArrayOutputStream(); ObjectOutputStream objOut = new java.io.ObjectOutputStream(bout); objOut.writeObject(a); byte[] data = bout.toByteArray(); bout.close(); objOut.close(); //deserializtion ByteArrayInputStream bin = new ByteArrayInputStream(data); ObjectInputStream objIn = new ObjectInputStream(bin); a1 = (ArrayList)objIn.readObject(); bin.close(); objIn.close(); } long time = System.currentTimeMillis()-start; if(a1.size() != a.size()){ System.out.println("Error happend, Invalid test!!!"); return; } else{ System.out.println("Serialization and Deserialization of " + a.size() + "*" + number +" items take:" + time + " ms."); } } public static void main(String[] args)throws Exception { // TODO code application logic here new Main(); } } import java.util.Date; import java.io.Serializable; public class MyObj implements Serializable{ private static final String NEWLINE = "\r\n"; private String m_name; private int m_age; private double m_salary; private Date m_hireDate; /** Creates a new instance of MyObj */ public MyObj(String name, int age, double salary, Date hireDate){ m_name = name; m_age = age; m_salary = salary; m_hireDate = hireDate; } public MyObj(){} public String toString() { StringBuffer sb = new StringBuffer(); sb.append("Name: " + m_name + NEWLINE); sb.append("Age: " + m_age + NEWLINE); sb.append("Salary: " + m_salary + NEWLINE); sb.append("Hire Date: " + m_hireDate.toString()); return sb.toString(); } }
坦率地讲,我以前看到过类似的测试,不过它不是针对你说的这个方面,而是针对ArrayList的性能。那个测试表明Java下ArrayList的缺省参数表现确实要比.Net下的ArrayList的缺省参数表现要强,但是如果能够适当调整ArrayList的构造参数,双方的比较结果完全可能倒过来。
IBM JDK,要想出1.5,还需要很长一段时间。我手头只有1.3的对比,反正IBM JDK比SUN同级的Server模式还要快一些。
事实上这部分的性能差异不是很大。我晚上在看看Code!
试过了,结果几乎一样。另外还用了Hashtable,结论基本一样。
.NET的表现很线性,这应该是JIT的特征。Java是越跑越快,可能Hotsopt JVM开始Kick in了。