西西河

主题:【倡议】Java SE 5.0和.NET 2.0擂台赛 -- Highway

共:💬34
分页树展主题 · 全看首页 上页
/ 3
下页 末页
                • 家园 用不同的参数,运行多次,其结果比较参差。

                  没有一个一直领先。但大多情况下,StringBuilder要好一些,或者好很多。

                  java -server -Xms64M -Xmx512M StringTest

                  StringBuffer Takes Total Time: 1763ms

                  StringBuilder Takes Total Time: 1127ms

                  java -server -Xms128M -Xmx256M StringTest

                  StringBuffer Takes Total Time: 2095ms

                  StringBuilder Takes Total Time: 952ms

                  java -server -Xms128M -Xmx512M StringTest

                  StringBuffer Takes Total Time: 2108ms

                  StringBuilder Takes Total Time: 888ms

                  java -server -Xms256M -Xmx512M StringTest

                  StringBuffer Takes Total Time: 1097ms

                  StringBuilder Takes Total Time: 1107ms

                  java -server -Xms512M -Xmx512M StringTest

                  StringBuffer Takes Total Time: 1235ms

                  StringBuilder Takes Total Time: 1079ms

                  缺省下,StringBuilder性能好些。

                  -Server的连续三次的结果为(总时间):

                  StringBuffer Takes Total Time: 5857ms

                  StringBuilder Takes Total Time: 3984ms

                  StringBuffer Takes Total Time: 5664ms

                  StringBuilder Takes Total Time: 3996ms

                  StringBuffer Takes Total Time: 5772ms

                  StringBuilder Takes Total Time: 3992ms

                  -Client的连续三次的结果为(总时间):

                  StringBuffer Takes Total Time: 7748ms

                  StringBuilder Takes Total Time: 6266ms

                  StringBuffer Takes Total Time: 7845ms

                  StringBuilder Takes Total Time: 6425ms

                  StringBuffer Takes Total Time: 7906ms

                  StringBuilder Takes Total Time: 6307ms

      • 家园 后天我才有时间对你的这个和下面那个问题进行测试

        请耐心等待。

        我的那个话题目前也只能够暂停了。

    • 家园 串行化/反串行化小测试中Java取得绝对性胜利!

      串行化/反串行化就是所谓的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();
          }
      }
      
      
      • 家园 一件有趣的事情

        如果把你程序中的a.Add(aObj)换成a.Add(aObj).toString(),我们将得到另外一组数据:

        Java without toString()

        Serialization and Deserialization of 50*1000 items take:2344 ms.

        Serialization and Deserialization of 500*100 items take:438 ms.

        Serialization and Deserialization of 5000*10 items take:359 ms.

        Serialization and Deserialization of 50000*1 items take:641 ms.

        Serialization and Deserialization of 50000*10 items take:11016 ms.

        Java with toString()

        Serialization and Deserialization of 50*1000 items take:1406 ms.

        Serialization and Deserialization of 500*100 items take:297 ms.

        Serialization and Deserialization of 5000*10 items take:329 ms.

        Serialization and Deserialization of 50000*1 items take:437 ms.

        Serialization and Deserialization of 50000*10 items take:35078 ms.

        .Net with toString();

        Serialization and Deserialization of 50*1000 items take:297 ms.

        Serialization and Deserialization of 500*100 items take:234 ms.

        Serialization and Deserialization of 5000*10 items take:313 ms.

        Serialization and Deserialization of 50000*1 items take:312 ms.

        Serialization and Deserialization of 50000*10 items take:4000 ms.

        我们可以看出,当不使用toString()的时候,明显是Java占上风,但是当使用toString()的时候,.Net则明显占了上风。看来.Net的问题应该是出在了深层目标的Serialization和Deserialization上面,而不是ArrayList层面。

        • 家园 有些技术,由于设计思想就不同,所以结果就会差别很大。比如

          Exception,Generics等等。

          曾近看过一篇文章,作者说尽量要避免在Session中使用自己定义的Ojbect.如果可能,要使用.NET的build-in type。因为自己定义的Object要使用“比较慢”的Binary Formatter来穿行化。而.NET的build-in type就要快很多。

          SOAP Formatter我也试验过,比Binary Formatter慢更多。

      • 家园 这个我试验过了,用的是微软自己的例子,结果也一样
      • 家园 我觉得你可以试着调整一下.Net的ArrayList的构造参数

        坦率地讲,我以前看到过类似的测试,不过它不是针对你说的这个方面,而是针对ArrayList的性能。那个测试表明Java下ArrayList的缺省参数表现确实要比.Net下的ArrayList的缺省参数表现要强,但是如果能够适当调整ArrayList的构造参数,双方的比较结果完全可能倒过来。

        • 家园 应该和这个没有关系.往ArrayList充填东西的时候时间是另算的!

          事实上这部分的性能差异不是很大。我晚上在看看Code!

          试过了,结果几乎一样。另外还用了Hashtable,结论基本一样。

          .NET的表现很线性,这应该是JIT的特征。Java是越跑越快,可能Hotsopt JVM开始Kick in了。

    • 家园 响应老轧同志的伟大号召,积极投身于擂台赛这场伟大的革命运动之中去

      按照常理,我应该直接评论Java 1.5和.Net 2.0这二者的优劣,可惜本人才疏学浅,觉得还是先熟悉一下Java 1.5和.Net 2.0,然后再展开Java 1.5和.Net 2.0之间的比较比较合适一些。同时为了不至于搞乱老轧同志的擂台赛主战场,我就另开一贴专门讨论Java 1.5的新特点作为擂台赛的分赛场,还请各位谅解。

    • 家园 Java SE 5.0和.NET 2.0 性能初试 (草案)

      性能是一个语言的关键,所以我想做的第一件事就是比较一下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 Server VM)重新测试

        接受了你克我服朋友的建议,使用了Java Server VM重新运行Java Program。令我吃惊的是在大多的测试中,Java有了非常大的提高(以前的Java VM两者区别不是很大,除非程序运行非常长的时间)。尤其是在Double和Long的运算上。总体上讲,Java和.NET这回是各有千秋。

        另外,-Xmx256M比原来的小了一倍。这个参数的意识是Java VM可以使用256MB的heap size.缺省的64M没法完成String部分测试 。事实上原先使用的-Xmx500M对性能没有什么影响,我测试了几组,没发现什么大的区别。

        [提示:原图站已失效]

      • 家园 一个二者性能比较的例子

        这是我从网上找来的,本来应该以文摘的方式转载,但是西西河的文章标题长度限制使得它成为不可能,我只好把它附在内容里了。

        .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):

        Composite Score: 207.78646505369562

        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.

      • 家园 到底什么是.net 呀

        那到它也是跟java一样的需拟机?

        不是编译成binary?

        • 家园 大差不差。微软不叫虚拟机,叫CLR

          Common Language Runtime.

          编译的结果叫IL(Intermedia language),和bytecode类似,可以反编译得到源程序。运行的时候,由CLR的JIT将IL转化为机器代码。

分页树展主题 · 全看首页 上页
/ 3
下页 末页


有趣有益,互惠互利;开阔视野,博采众长。
虚拟的网络,真实的人。天南地北客,相逢皆朋友

Copyright © cchere 西西河