译器如果发现在这个映射表中没有标记这个方法,就会将这个方法的IL代码编译成CPU指令,然后分配在一个内存空间上,然后在这个映射表中记录下这个方法名和方法入口对应的内存地址,然后通过JMP指令跳转到函数中去。当下次再产生对这个方法的调用时,即时编译器因为已经知道了这个方法对应的内存地址,因此就会直接通过JMP指令跳转,而不会再次编译这段代码。
因此可以看出,只要程序所有的代码都被执行过一次了,那么整个程序就都会被编译成CPU指令保存在内存中。在此之后托管程序跟非托管程序的执行效率就基本上没什么区别了——当然,托管程序需要从那个映射表中取函数地址,而非托管
程序中方法的地址是已知的。
因此,理论上在某些情况下(比如win service、iis等长期循环执行的程序),托管程序的性能并不会比非托管程序的性能差多少。而且,非托管程序因为要考虑兼容性必须兼容标准指令,而非托管程序因为是运行时编译的,非常清楚操作系统环境,因此可以做针对性的优化。
不过,因为即时编译的结果是保存在内存中的,因此对于那些会频繁启动的程序来讲,其启动过程是会比较慢的——因为每次启动都需要加载CLR并做一次即时编译。
至此,在了解到了托管程序与非托管程序在加载、执行时的区别,我们就可以更加清楚怎样才能充分利用非托管程序的优点、避免其缺点,从而发挥他的最大价值、避免使用时走入误区。
评论
#4楼 2008-04-17 08:27 young5335 [未
注册用户] 用NGEN.EXE生成后的速度是不是能快些?WINFORM程序,特别是使用了一些界面控件后,速度慢的让人无法忍受。
NGEN生成的机器码跟WIN32程序相比,速度快还是慢呢? #6楼 2008-04-17 08:30 Da Vinci 原理比较容易理解 但是要清楚在某些情况下.NET程序不一定比其他的非托管的慢 因为CLR会优化一部分代码的运行期过程 这比Java要快多了 甚至有些情况执行速度和非托管的C++差不多
#8楼 2008-04-17 08:32 Da Vinci @young5335
情况不同 速度也不同 一般来说NGEN的机器码不如JIT的速度 因为优化不如JIT
#9楼 2008-04-17 08:38 lbq1221119 不错 呵呵
系统如何启动托管app,可以参考sscli团队里面的一篇的详细介绍.
#10楼 2008-04-17 08:40 lbq1221119 也就是如果不使用ngen在第一次运行的时候需要便已成为native code.但是这个时候是做了很多的编译器优化,然后把结果存起来,以后经常使用的时候就快多了,一点也不比非托管的慢
#11楼 2008-04-17 08:42 lbq1221119 @Da Vinci
ngen只是针对一套比较通用的cpu指令进行编译的,为了考虑通用性.
jit有很对正对当前的特定平台的编译优化动作.
#13楼 2008-04-17 08:49 Da Vinci 可以看看jeffer的那本书 很详细的讲了
#14楼 2008-04-17 08:58 gussing 这个不是MSDN中的.net概论那一章嘛。
大家
学习.net的时候,难道连概论都不看的?
#18楼 [楼主] 2008-04-17 09:26 没有昵称 @Justin
哈哈,偶技穷了呵。这东东专业术语蛮多的,我还真不知道咋弄个通俗点的东西描述呵。
#21楼 2008-04-17 09:50 簡簡⿺單單.. 那么楼主你有没有.Net的针对性优化方案? 譬如: 托管程序预编译等..
#22楼 2008-04-17 09:55 oweb [未注册用户] 确实比别的都慢吗? #25楼 2008-04-17 11:00 jipp.cn [未注册用户] .Net程序一点多不慢,
#26楼 2008-04-17 11:09 风海迷沙 比起ASP来,
asp.NET已经无比快了。
#27楼 2008-04-17 11:13 成长的强强 确实在很多情况下和其它语言的程序比起来都要慢些,,
#28楼 2008-04-17 11:17 jipp.cn [未注册用户] 刚才忘了说明一点,运行快不快,决定因素在写程序的人,而不是工具,
#29楼 2008-04-17 11:27 PerfectD