评测报告:.NET的性能仍然远远落后于Java<o:p></o:p>
每个人都看过各种不同的benchmark,有证明.NET比Java快的,也有证明Java比.NET快的。在某些人的手里,benchmark是一面魔镜,透过它能看到想看的东西。所以,当这位名为Cameron的先生要开始在.NET和Java之间做一个benchmark时,他认为自己就是在浪费时间,因为肯定会有人来证明.NET比Java快。<o:p></o:p>
顺便地,Cameron先生提出了10条“不要用于在.NET和Java之间做选择”的理由,其中包括:<o:p></o:p>
Ø 在某一组特定的benchmark中,某一个比另一个快一点;<o:p></o:p>
Ø Microsoft或Sun(或者Oracle、IBM……)的报告说其中一个比另一个好得多;<o:p></o:p>
Ø 你喜欢(或不喜欢)Bill Gates或者Scott McNeally(或者Larry Ellison);<o:p></o:p>
Ø 你认为Microsoft或者Sun(或者IBM或者Oracle)很邪恶(或者很伟大);<o:p></o:p>
Ø 你在TheServerSide.com或者GotDotNet.com(或者Microsoft.com)读了一篇“没有偏见”的文章;<o:p></o:p>
实际上,这次benchmark源于Cameron与tRolf两人在TheServerSide.com网站的一次关于Web服务性能的争吵(http://www.theserverside.com/reviews/thread.jsp?thread_id=19226)。在这次的benchmark中,Cameron测试了下列版本:<o:p></o:p>
在代码方面,Cameron主要选择了大量ArrayList来进行测试。下列是他的测试代码:<o:p></o:p>
C#<o:p></o:p>
// C# Create 100,000 people in an ArrayList and access them
using System;
using System.Collections;
<o:p></o:p>
public class ManyPeople
{
public static void Main()
{
for (int i = 0; i < 100; i++)
test(i);
}
public static void test(int iIter)
{
DateTime start = DateTime.Now;
for (int i = 0; i < 20; i++)
new ManyPeople().Average();
DateTime finish = DateTime.Now;
Console.WriteLine("Total time for iteration " + iIter + ": " + (finish - start));
}
<o:p></o:p>
private long Average()
{
ArrayList list = new ArrayList(100000);
for (int i = 0; i < 100000; i++)
list.Add(new Person(i, "John " + i));
<o:p></o:p>
long silly = 0;
foreach (Person p in list)
silly += p.Id;
return silly / 100000;
}
}
<o:p></o:p>
// Person.cs: a very simple guy
public class Person
{
int id;
string name;
<o:p></o:p>
public Person(int anId, string aName)
{
this.id = anId;
this.name = aName;
}
<o:p></o:p>
public int Id
{
get { return this.id; }
}
}
Java:<o:p></o:p>
// Java Create 100,000 people in an ArrayList and access them
import java.util.*;
<o:p></o:p>
public class ManyPeople
{
public static void main(String[] args)
{
for (int i = 0; i < 100; i++)
test(i);
}
public static void test(int iIter)
{
long start = System.currentTimeMillis();
for (int i = 0; i < 20; i++)
new ManyPeople().average();
long finish = System.currentTimeMillis();
System.out.println("Total time for iteration " + iIter + ": " + (finish - start));
}
<o:p></o:p>
private long average()
{
ArrayList list = new ArrayList(100000);
for (int i = 0; i < 100000; i++)
list.add(new Person(i, "John " + i));
<o:p></o:p>
long silly = 0;
for (int i = 0; i < 100000; i++)
silly += ((Person)list.get(i)).getId();
return silly;
}
}
<o:p></o:p>
// Person.java: a very simple guy
class Person
{
private int id;
private String name;
<o:p></o:p>
public Person(int anId, String aName)
{
this.id = anId;
this.name = aName;
}
<o:p></o:p>
public int getId()
{
return this.id;
}
}
Cameron所用的测试机器是P3 1GHz、1G内存的笔记本,操作系统是Windows 2000 SP2。下列是在.NET上测试的结果(取最好的6次):<o:p></o:p>
.NET 1.0sp2:<o:p></o:p>
.NET 1.1:<o:p></o:p>
可以看到,同样的代码在.NET 1.1上比.NET 1.0 SP2上慢了大约15%。这是一个很奇怪的现象。并且,Cameron观察到,.NET上同样代码的运行速度并不随运行次数的增加而提高,说明.NET CLR只是简单地进行了JIT编译。而在Hotspot Server上,不仅开始时的性能就有优势,而且速度还会不断提高:<o:p></o:p>
Sun Hotspot Server JVM from JDK 1.4.1_02:<o:p></o:p>