西西河

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

共:💬34 新:
全看树展主题 · 分页首页 上页
/ 3
下页 末页
家园 【倡议】Java SE 5.0和.NET 2.0擂台赛

现在,Java的一个重要版本终于面世了。不管怎么说,这是继Java 1.2之后的一个阶段性发展。而微软的.NET 2.0 Beta版本已经发布一段时间了。这两种技术在今后一段时间内将是应用程序市场开发的主流。希望大家就这两种技术提出自己的看法。不限形势,不限内容,大家尽可畅所欲言。比如两者性能有什么区别,功能有什么差异,Garbage Collection技术细节上有何异同,安装,发布的难度如何,和以往版本的兼容性如何等等。

总之一句话,希望大家踊跃发言!

家园 哈哈.. 俺发言

俺一 样都不会...吼吼..

家园 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的问题我将今后专门讨论!

家园 到底什么是.net 呀

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

不是编译成binary?

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

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

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.

家园 Thanks. Very useful information!
家园 那~~~Java方面老兄用的是啥虚拟机阿?

一般来说IBM的虚拟机要比SUN的快上那么两三倍吧?

实在不行,SUN的虚拟机执行的时候用上-server模式也会加速的

看老兄上来就是“java -Xmx500M Benchmark”,心里就有气~~~~

摆明了是要SUN出洋相好看的嘛~~!

代表java用户鄙视一下

家园 自打Java 2出世以后,Sun的JVM就一直是最流行的,最近几年Java

论坛推荐的都是Hotspot Sun JVM.

Server JVM在长时间运行的程序中会有一些性能提高,对于Client application,还是Client 参数比较好。这样程序载入快,Memory footprint小。

-Xmx500M不是一个好的例子。我只是想让Java能完成测试,不要出现Out of memory 问题。你可以自己试试看其他参数。

另外,如果你方便的话,可以帮我比较一下Sun JVM和IBM JVM有什么区别。

谢谢参与!!

家园 测试修正(使用Java Server VM)重新测试

接受了你克我服朋友的建议,使用了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的新特点作为擂台赛的分赛场,还请各位谅解。

家园 串行化/反串行化小测试中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();
    }
}

家园 我觉得你可以试着调整一下.Net的ArrayList的构造参数

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

家园 我在java1.4下用server模式,成绩一下比client模式提高一大截

IBM JDK,要想出1.5,还需要很长一段时间。我手头只有1.3的对比,反正IBM JDK比SUN同级的Server模式还要快一些。

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

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

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

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

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


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

Copyright © cchere 西西河