跨平台的客场交锋:.NET vs. JAVA on Linux

自从 .net 推出以来, .net 与 java 之间的明争暗斗就一直没有停息过,但是战斗一直都仅限于理论层面上,互相都只摆出自己的一堆大道理,口水都快淹死人了,但却从来没有真刀真枪的干上一仗。为什么呢?原因是 .net 一直在家里不出来,哪里都不去。他们没有机会真正的碰过面。

但现在她们终于有机会真正进行一场公平的竞赛了,一年前就一定开始的 .net 开放源码计划 MONO 不久前刚刚推出了最新版本 0.13 ,虽然还是个开发中的产品,但是我已经忍不住要把她请出来和 java 过过招了。

再进行枯燥的数据对比以前,请先看一段浪漫的故事,了解一下 .net , mono 之间的关系,谢谢。 :)

话说很 java 不服气,虽然 java 上门去找 .net 比划过几招,但是 .net 的父亲老比对她很不欢迎,而且好象也没比赢。 Java 很生气:“有什么了不起,不就是比我年轻几岁吗?老娘当年风光的时候你还没出生呢,只在家算什么厉害,在你们家我当然比不过你了,有种出来呀!”。

这边老麦很是得意:“大家看看,我还当 .net 是什么大美女呢,连客都不敢见,多半笨得连话都说不清楚。看我们家 java 多好,人见人爱,上得厅堂下得厨房,让她去哪就去哪,半句都不罗嗦。”

这边老比答话了:“谁说咱们家 .net 不行?她不仅系出名门,天资国色,而且能听懂几乎所有国家的语言,我还专门请了编织大师安德斯到我们家来专门教她刺绣。不过她是大家闺秀,岂能跟你们家那个野丫头一样到处乱跑,谁都可以摸一把。再说了,这里大部分的土地都属于我们家,她出不出去其实都一样。”

.net 虽然生活无虑,每天有人伺候,但是还是经常照着镜子叹气:“唉,都怪我老爸,限制人家自由,虽然可以每天穿好衣服,但是只有我们家的人才能看到我,我想让世界上所有的人都来赞叹我的美丽,让各种人用不同的语言对我说:‘我爱你’。”。

.net 的话有一天被一个英俊的小伙子听到了,他就是开发出了 Linux 下著名的 x-windows 系统 gnome 的 ximian 。他第一次见到 .net 就被她的美貌给深深打动了,他对身旁的人说:“我终于发现,她就是我真正想要的”。他还发现 .net 是 microsoft 家族中唯一一个想要出去的人。于是他每天抽空跟她讲一些发生在他们那里的美好的故事,讲他们那里有很多很多勤劳善良的人,那里没有等级,没有剥削,大家都无私的贡献出自己的劳动成果让大家一起来分享。都自觉的遵守着他们自己制定的平等的制度 GNU ,那个繁荣自由的国度就是 Linux 。

“啊? Linux !” .net 吃惊的叫了起来,“我知道!我爸爸说那里是坏蛋居住的地方,那里的人们很穷,他们自己不知道怎么去赚钱维生,每天只想到去如何攻击掠夺别人的家园,还一直嚷嚷着要把我们的家给拆散,要把我们家里的东西全部抢走!”

“那些并不是真的” ximian 平静的说:“我可以带你去那里看看,美丽的小姐,你会被他们的勤劳善良和伟大给感动的”。

“真的吗?” .net 美丽的大眼睛里闪动着向往和好奇,然后坚定的说:“我一定要去那里看看,即使是父亲不允许,我也一定要去!”。

当晚, .net 脱下高贵的华服,换上粗陋的布衣,跟 ximian 出发了。

此时,老比其实把一切都看在了眼里,但是他并没有阻止 ximian ,他叹了口气说道:“去吧,孩子,毕竟时代不一样了,你一定会成为我们家族最大的荣耀的”。同时,他的嘴角闪过了一丝不容易被察觉的微笑,精明的老比此刻正想着什么呢?

故事还在发展,现在还看不到任何结局, .net 在 linux 国度里改名叫做 mono ,她从最基本的开始学起,慢慢的适应了 linux 的生活,一年过去了, mono 终于推出了最新的版本 0.13 ,在这个版本里,我们看到了很多重要的进步,慢慢的开始显露出了 .net 的才华和美丽。

下面,我们要做一些测试,看看 .net 是否真正的适应了 linux 的生活,和她原来比起来究竟有多大的差距,同时,我们还邀请到了 java ,做为友情客串,她只是提供一些参考性的测试数据。当然,这并不是一场和 java 很正式的比赛,有点难为 mono 了,毕竟, mono 还只是一款正在开发中的产品。

首先,我们来进行一个循环测试,循环测试被很多人指责太过于简单,不能很好的反映出真实的运行环境,但是它的优点也在于它的简单,因为程序越复杂,写法就越多,争论的焦点就变成了如何对程序进行最优化,例如著名的宠物店大战。同时也因为曾经有一个很有名的测试,是对一个 jsp 的循环速度测试,结果是 jsp 是 7 秒, asp 和 php 都是 80 多秒,被 java 爱好者津津乐道了很久,我当时也用 asp.net 测试过是 2 秒,当然操作系统环境不一样,不具备太大参考价值。也是后话。

下面是用于进行测试的程序,主要功能就是执行十亿次循环,循环里面有一个加法运算和一个赋值运算。硬件测试环境为: P3-M 1.2G, 512M, 30G (笔记本电脑)。软件测试环境为: Mono 0.13 for Linux, Mono 0.13 for Windows, .Net Framework SDK 1.0.3705 (中文版) , J2SE 1.4.0_01 for Linux , J2SE 1.4.0_01 for Windows, Windows 操作系统为: Windows XP 中文版, Linux 操作系统为: Mandrake Linux 8.2 。编译方式均采用默认选项。输出的结果均为运行所需时间,单位为毫秒。

以下是该测试程序的 C# 程序代码:

using System;

class test

{

static void Main (string[] args)

{

int temp;

DateTime a = DateTime.Now;

for(int i = 0; i < 1000000000; i++)

{

temp = 1+1;

}

DateTime b = DateTime.Now;

TimeSpan c = b - a;

Console.WriteLine(c.TotalMilliseconds);

}

}

以下是相应的 java 程序代码:

import java.util.Date;

public class test

{

public static void main(String args[])

{

Date before = new Date();

long a,b;

int temp;

a = before.getTime();

for(int i = 0; i < 1000000000; i++)

{

temp = 1 + 1;

}

Date after = new Date();

b = after.getTime();

System.out.println(b - a);

}

}

由于 mono 自己有编译器和执行环境,那么我们就要分别对编译器和执行环境进行测试和对比,下面是测试过程和结果:

( 所有测试结果全部是运行十次,取最短的一次时间 )

在 windows 下的测试:

使用 mono 的 C# 编译器编译以上代码命令行:

monomcs /out:mtest.exe test.cs

提示编译成功,产生一个 mtest.exe 文件。

直接输入 mtest ,采用 microsoft 的 .net 运行环境来运行,程序运行成功,没有任何错误提示,显示运行结果为: 2613

输入 mono mtest.exe ,采用 mono 的 .net 运行环境来运行,程序运行成功,没有任何错误提示,显示运行结果为: 4336

使用 microsoft 的 C# 编译器编译以上代码命令行:

csc /out:wtest test.cs

提示编译成功,但产生了一个警告:“ temp 变量已经被赋值,但是从未使用过”,这个警告是正常的,我们可以不用管它,它也不会给这次测试带来任何影响。同时生成了一个 wtest.exe 文件。

直接输入 wtest ,采用 microsoft 的 .net 运行环境来运行,程序运行成功,没有任何错误提示,显示运行结果为: 2563

输入 mono wtest.test ,采用 mono 的 .net 运行环境来运行,程序运行成功,没有任何错误提示,显示运行结果为: 2654

使用 java 编译器编译 java 源文件:

javac test.java

结果没有任何错误和警告提示,并生成一个 test.class 文件

输入: java test ,采用 java 运行环境来运行,程序运行成功,没有任何错误提示,显示运行结果为: 6039

在 linux 下的测试:

将以上三个可执行文件: mtest.exe , wtest.exe, test.class 及源码文件 test.cs , test.java 拷贝到 linux 系统下。

具体操作和 windows 下没多大区别,这里只报告一下结果:

mono mtest.exe 结果为 4205

mono wtest.exe 结果为 2527

java test 结果为 4197

然后用 linux 下的编译器分别重新编译了 Mono 和 Java 的源码,运行:

mono test.exe 结果为 4205

java test 结果为 5876

这里值得一提的是, mono 的 for windows 版和 for linux 版编译出来的代码没有任何差别,运行结果也几乎没什么差距。 Java 的 for windows 版和 for linux 版编译出来的两个 class 文件有差异,并且运行结果也有很大的差距。

另外,由于 mono 在两个平台下编译出来的可执行文件完全一样,所以没有将 linux 下编译的程序放到 windows 上进行测试,仅仅将 java 在 linux 下编译的可执行程序放到 windows 上进行测试,结果是 5087 。

以下是这次测试结果的对照表 ( 毫秒 ) :

** 编译器 **

** 平台 **

|

** .Net Framework **

|

** MONO.Net **

|

** JAVA for Win **

|

** JAVA for Linux **

---|---|---|---|---

** .Net Framework **

|

2563

|

2613

|

-

|

-

** Windows **

|

2654(Mono)

|

4336(Mono)

|

6039 ( java )

|

5087 (java)

** Linux **

|

2527(Mono)

|

4205(Mono)

|

4197 ( java )

|

5876 ( java )

通过比较这个测试结果,我们发现了两个很有趣的现象,一个是 mono 的 jit 在运行原生 .net 编译器编译出来的可执行文件时,效果很好,和原生 .net 的 jit 运行效率很接近。但是运行它自己的编译器编译出来的可执行文件时,效率却变得很差,这种情况在 windows 和 linux 下都一样。但是原生 .net 的 jit 运行 mono 编译出来的可执行文件却又还可以。难道是 mono 不喜欢自己的亲生儿子?:)

还有一个是 java 的“跨平台”能力最强,在 windows 下编译的程序,放到 linux 下执行起来速度比较快,在 linux 下编译的程序放到 windows 下执行比较快,难道这就是 java 为跨平台能力进行的优化? :)

另外,值得一提的就是在 windows 下用 java 编译的本程序直接放到 linux 下使用会产生两个警告。重新编译以后警告消失。

在这次的测试中, mono 不负众望,以远远出乎我们意料的好成绩和 .net 站在了同一条线上(甚至可以看到本次测试中的最好成绩竟然属于 mono ,但是我认为几十毫秒的差距完全可以忽略不计,不能认为 mono 的效率超过了 .net )。同时,无论是在 windows 平台,还是在 linux 平台, mono 的表现都超过了 java 。要知道,她还仅仅只是一个在开发中的产品。

.net 拥有最先进的技术,拥有最速的效率,现在,她不仅能跨语言,还能跨平台,甚至还开放了源代码, Mono 的开发计划中就有 Linux, Power PC, Solaris, Strong ARM 等版本。还有微软支持的 FreeBSD 版本。

当然, java 也不会是省油的灯,不知道 SUN 的下步棋会如何走,才能得以抵挡住 .net 大军的疯狂进攻。

Published At
Categories with Web编程
Tagged with
comments powered by Disqus