(网摘)Net的程序运行效率比VC++低?不!翻译自国外的一篇文章

来源:互联网 发布:西北偏北 刘东明 知乎 编辑:程序博客网 时间:2024/05/16 06:11

以下摘自:http://bbs.gameres.com/showthread.asp?threadid=99400

.Net的程序运行效率比VC++低?不!翻译自国外的一篇文章

这是我自己翻译的一篇文章,由于本人英语有限,所以其中会有翻译错误或者不准确的地方,建议英文好的朋友看原文。
原文:
http://www.grimes.demon.co.uk/dotnet/man_unman.htm

 

托管代码(.net)比非托管代码(vc++)慢吗?

如果你用上面这个问题去问每一个人,基本上每个人都会回答,肯定会慢! 那么他们说的是正确的吗? 不,并不正确。 问题在于,绝大多数人认为.Net只是一个基于运行库的框架,就像Java或者VB,或者他们甚至以为.Net使用像Java一样的虚拟机系统。 他们并沒考虑到程序本身,沒考虑到程序是用来干什么,也没有考虑到访问网络或者磁盘的速度因素。简单来说,就是他们根本没有思考!

.NET并不像那种运行库(VB或者Java)。 它是一个经过精心构思的,并且微软在其身上下了极大功夫的框架,以保证它的良好运行。 在这篇文章 我将给大家展示一些将需要大量运算的代码,并且将他编译成托管以及非托管代码。 然后我将测量这两个库分别的表现。 你将看到, 并不会因为这是.net程序就自动要比c++程序慢,事实是,在某些情况,托管代码甚至比非托管代码更快。

题外话(我自己补充的,原文没有提到):
.NET的运行机制,由于本人现在研究的项目跟.Net库底层有些关系,所以多少了解一些,现在简单给大家介绍一下。
基本上每个人都知道的是,所有.Net语言都将被编译成为一个叫做IL汇编的中间语言。但是计算机是如何执行这个中间代码的,却是很多人不知道,甚至理解错误了的。
JIT是.NET程序运行的重要部件之一,全称是即时编译器。我刚才说的误解,就是很多人(绝对不是少数,问了很多c++程序员,10个有9个这种想法)都以为JIT其实就是跟Java VM差不多的东西,是一个Interpreter,在运行时读取IL汇编代码,然后模拟成x86代码(也就是俗称的虚拟机)。但是事实上,.NET使用的是更为高级的技术。 .Net程序被加载入内存以后,当某段IL代码被第一次运行的时候,JIT编译器就会将这段IL代码,全部编译成本地代码,然后再执行。这也就是为什么.NET程序第一次运行都启动很慢的原因! 随.NET库,微软还附带了一个工具,可以事先将.NET程序所有的IL代码都编译成本地代码并保存在缓存区中,这样一来,这个程序就跟c++编译的一模一样了,没有任何区别,运行时也可以脱离JIT了(这里不要混淆了,这里不是说可以脱离.NET库,而是说不需要在进行即时编译这个过程了)。所以,请不要将.NET和Java混为一谈,两个的运行效率根本不是一个等级的!

作为测试算法,我们选中了FFT(Fast Fourier Transform),这是一个将跟时间有关系的数据(例如音乐)转换成他应有的频率信息的算法。
这个算法有很多种,如果你用Google搜索会发现很多,这里我选中了Real Discrete Fourier Transform, 因为他比较简单明了,比较好修改。 我将其复制了4份,分别用于测试托管的C++, C++/CLI,C#。

非托管的代码我只是将其函数名称改成了fourier,并且加入了__declspec(dllexport)用来导出。
托管的代码改动的要稍多些:

    * 方法参数改成了托管的Array, 并且使用Array::Length来代替额外的长度参数
    * 涉及到三角函数的地方都改为使用Math类下的方法
    * 算法被作为一个公开类的静态成员导出

然后我把托管的c++代码转换成了c#,只做了极小的变化(大多数是语法上以及申明上的改动)
最后,我又将托管的c++代码转换成了C++/CLI

然后我们将所有版本都分别编译几个不同的版本:未优化版,空间优化,速度优化.

结果:
我将这些程序分别在两台电脑上进行了测试,一台是装了.net 2.0的 XPSP2,处理器是PIII 850, 512MB内存。 另外一台是Vista build 5321,处理器是2GHz 移动PIV,1G内存,每次测试我都是取100次算法运算的平均值,结果单位是毫秒,以下是PIII电脑的运行结果:
            沒优化   进行了空间优化  进行了速度优化
Unmanaged  92.88 ± 0.09  88.23 ± 0.09  68.48 ± 0.03
Managed C++  72.89 ± 0.03  72.26 ± 0.04  71.35 ± 0.06
C++/CLI  73.00 ± 0.05  72.32 ± 0.03  71.44 ± 0.04
C# Managed  72.21 ± 0.04  69.97 ± 0.08

PIV电脑的结果:
            沒优化   进行了空间优化  进行了速度优化
Unmanaged  45.2 ± 0.1  30.04 ± 0.04  23.06 ± 0.04
Managed C++  23.5 ± 0.1  23.17 ± 0.08  23.36 ± 0.07
C++/CLI  23.5 ± 0.1  23.11 ± 0.07  23.80 ± 0.05
C# Managed  23.7 ± 0.1  22.78 ± 0.03

可以看出,非托管代码在不同的优化方案上存在很大的效率差异,PIII上不优化比优化慢35%,在PIV上也是。 在这个简陋的统计上表明,不管是哪种优化方案,管理代码在运行效率上并没有太大区别,编译器和连接器并没有影响到运行效率太多, 我在后面会说更多关于这方面的信息。
奇怪的是,在Vista下,管理代码进行空间优化甚至比进行速度优化速度更快!

C#的结果跟托管的C++比起来,并没有太大区别,但是可以看到, 优化过的c#代码比优化过的托管C++代码要稍快些

现在来比较以下托管代码和非托管代码的结果。 在不优化的情况下,托管代码远远快于非托管代码,这个差距在优化空间后被稍微缩短了点,只有在进行速度优化后,非托管代码才比托管代码稍稍快上一点
非托管代码和C#代码的差别只有3%左右,不过,c#代码仍然比c++的更快! 

.NET的编译器(在这个情况下是托管的C++代码) 可以看成是与非托管C++编译器的Parser引擎是等价的。编译器将生成类,方法等的表,然后进行了一系列的高等级优化。 .NET真正的非托管编译器其实是JIT(即时编译器):这才是程序真正转换成低等級的x86代码的地方..NET编译器和JIT编译的组合,其实跟非托管C++编译器等价的,唯一的不同是,.Net被分成了两个部分.事实上,JIT在运行托管代码时,对.NET程序针对客户电脑进行了优化,而不是像非托管代码那样是在程序员电脑上进行的优化。结果表明,托管C++代码和c#代码的优化设置带来的影响非常小。 显而易见的是,C#代码至少是跟C++代码同样高效。

记住! 在.NET中没有任何一个部分是自动就必C++代码慢的,运行效率完全取决于程序员。任何一个告诉你托管代码比非托管代码慢的人,都是没有考虑到.NET运行机制的人,简单的说,就是对.NET一窍不通!

 
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 月季叶子掉光了怎么办 红鹦鹉鱼变白了怎么办 红鹦鹉鱼生病了怎么办 泡鱿鱼干没有碱怎么办 彩虹6号买了68怎么办 r6买了乞丐版怎么办 狙击精英3闪退怎么办 踩到地雷怎么办 知乎 蛋糕海绵灌胶了怎么办 蝴蝶的翅膀断了怎么办 培乐多彩泥干了怎么办 ps4被ban机了怎么办 塔吊离建筑物8米怎么办 手表带掉边缘皮怎么办 脸皮肤过敏痒肿怎么办 脸过敏发红发肿怎么办 皮肤过敏又红又肿怎么办 春天脸过敏发红痒怎么办 皮卡车后斗生锈怎么办 没带卸妆的东西怎么办 审车尾气过不了怎么办 违章停车条丢了怎么办 停车被城管贴条怎么办 违停告知单丢了怎么办 交通事故责任认定书不服怎么办 对交通事故认定书有异议怎么办 老婆不让我碰她怎么办 车被城管拖走了怎么办 共享汽车没油了怎么办 车被蹭了人跑了怎么办 遇见碰瓷的人怎么办 遇到老人碰瓷的怎么办 打了碰瓷的怎么办 倒车入库打晚了怎么办 上班停车费太贵怎么办 黄疸回家小孩不爱吃母乳怎么办 黄金棒开关坏了怎么办 在一家莆田系医院上班怎么办 被莆田医院骗了怎么办 痘痘红肿有脓包怎么办 换届选举候选人自动退出竞选怎么办