.NET比C/C++更快?
C#和JAVA以及Python一样,是解释性语言(Interpreted language)的一种,这类语言和编译性语言(Compiled language)如C/C++/FORTRAN的区别在于后者将源代码编译为机器代码执行,而前者通过将源代码编译为平台无关的bytecode,然后再通过虚拟机的“即时编译”(Just-in-time compilation, JIT)在执行时“解释”为机器代码然后运行。在跨平台性和代码易于调试维护上前者比后者有绝对优势,而且往往添加了一些关键特性比如garbage collection。
通常编译性语言比解释性语言快,但并不是一定的。两者执行效率差距完全取决于编译器和虚拟机的质量。.NET平台就是一个很好的例子。
.NET 是微软的一种应用程序构架(Framework),C#/C++/VB等源代码可以通过微软的编译器先生成一种称为CIL(Common Intermediate Language, 通用中间语言)的bytecode,然后通过.net的虚拟机编译为机器代码执行。C#是.NET的默认语言,你也许会争论C++是.NET的默认语言,因为其可控性更强,但这种争论是错误的,因为:C#和managed C++生成的都是相同的CIL bytecode,而C++语言本身显然缺少C#的新特性。
即使是C#.NET和unmanaged C++(非生成CIL的C++)相比,前者执行效率上也有优势。下面我通过实例(N体问题的数值解)来比较C#和C++(unmanaged)的运行效率,采用了computer language shootout中的源代码,并做了少量修改,但算法都是一样的。我修改过的代码在下面下载:
C# 源代码文件 nbody.cs
C 源代码文件 nbody.c
C++ 源代码文件 nbody.cpp
编译环境为:
CPU: Pentium 4 3.0Ghz
OS: Windows XP / SP2
Memory: 1G
Compilers:
Visual Studio 08: .NET(3.5), C# 编译器 csc.exe (3.5.21022.8), C++/C 编译器 cl.exe(15.00.21022.08),
Cygwin中的gcc/g++(3.4.4)
另外对C#编译后的.exe的bytecode还可以通过ngen.exe进行预编译为机器码放入Native Image Cache(C:\windows\assembler)中尝试加快执行速度(免去对CIL的JIT时间)。
编译和运行都在cygwin的shell下通过命令行执行,编译命令行和程序执行的时间见下。
C# (csc.exe)
$ csc /o nbody.cs
9.604s, 9.587s, 9.593s, 平均值 9.595s
C# (csc.exe with ngen.exe)
$ csc /o nbody.cs
$ ngen install nbody.exe
9.000s, 8.984s, 9.000s, 平均值 8.995s
C (gcc)
$ gcc -O3 nbody.c -o body
10.859s, 10.781s, 10.828s, 平均值 10.823s
C (cl.exe)
$ cl /Ox nbody.c
12.029s, 12.008s, 12.004s, 平均值 12.014s
C++ (g++)
$ g++ -O3 nbody.cpp -o nbody
10.938s, 11.016s, 11.015s, 平均值 10.990s
c++ (cl.exe)
$ cl /Ox nbody.cpp
12.584s, 12.572s, 12.528s, 平均值 12.561s
执行的命令行都是
$ time ./nbody.exe 20000000
通过比较得出结论:
1. 算法才是王道。决定效率的第一因素是算法而不是语言。
2. 解释性语言和编译性语言的执行效率取决于解释器和编译器,而.NET的执行效率确实是高度优化的。从上面的结果可以看出.NET的虚拟机比gcc或者微软自身的C++编译器生成的机器代码效率都要高(9.595s vs 10.823s)。也许你会说这个N体问题特殊,对其他某些问题C/C++会比C#快,但两者效率肯定是一个数量级别的。
3. 微软的C++编译器很烂。在都是用优化选项的前提下,无论是C还是C++代码,微软的cl.exe编译器都比GCC生成的代码慢。C代码慢11%而C++慢了14%.
4. 从对比使用ngen和不用ngen的结果来看,后者仅仅比前者慢了6.7%(0.6秒),可见.NET对CIL的执行时编译为机器的效率是很高的。
总之,C#.NET的前途是光明的,考虑到Windows的market share有90%,未来的趋势将是:C#.NET打败JAVA,千秋万代一统江湖 ![]()
阅读(785 次)

七月 19th, 2008 at 10:30 下午
Java万岁!
七月 20th, 2008 at 5:13 上午
打败java有2个问题
1. J2ME
2. Linux支持
七月 21st, 2008 at 8:35 上午
微软似乎对移植.NET平台并不热心,虽然已经有基于移动Windows的.NET版本和开源的Mono. 微软已经将CLI和C#提交到了ECMA和ISO,不过据说提交的部分只占.NET构架的大约10%。