在.net中为什么第一次执行会慢?
众所周知.NET在第一次执行的时比第二第三次的效率要低很多,最常见的就是ASP.NET中请求第一个页面的时候要等上一段时间,而后面任意刷新响应都非常迅速,那么是什么原因导致的呢?为什么微软不解决这个问题呢?
问题
首先大家可以在心底回答这几个问题,这也是读完本文之后会陆续解决的问题。
1.生成就是编译吗?
2.既然执行过一次之后效率会高很多为什么微软不解决这样的问题呢?
3.预编译比JITCompiler的方式好吗?
效率比较
第一次执行耗费了399
第二次执行耗费了5
为什么差这么多呢?后面就让我们来揭晓。
注:单位不是ms(毫秒)
生成就是编译吗?
首先我先回答第一个问题:生成也是编译(语言编译),只不过不是编译成机器码(汇编),而是“IL”,但一般人会听到编译都联想到编译成机器码(汇编),所以大家最好叫生成。
既然在生成的时候没有编译成机器码,那么计算机是如何执行的呢?下面我们来看描述了方法首次调用的一幅图,摘自网络。
可以看出,在WriteLine下有个JITCompiler,没错就是这个函数帮我们把WriteLine编译成了机器码。
那当第二次执行的时候JITCompiler会变成本地代码,也就是说JITCompiler不会再次执行了,顺带得到的好处就是效率提升了。
既然执行过一次之后效率会高很多为什么微软不解决这样的问题呢?
为什么微软不再VS生成的时候就编译成机器码呢?
其实微软有提供相关的设置(预编译),但不推荐使用。
微软既然提供了预编译为什么不把它设为默认的呢?
这个就得跳到第三个问题咯,大家继续往下看。
预编译比默认的方式好吗?
多平台支持
再写完一个程序时(WinForm比较常见)可以发现可疑同时运行在x86和x64的平台上,那为什么x64的操作系统一开始会有那么多的x86软件兼容问题呢?
其实针对x86和x64平台的指令是有区别的,深入的我也不太了解,有大牛可以细说说。
那为什么一次生成可以同时在x64和x86上同时运行呢?
原因其实很简单:JITCompiler是在执行方法时才会将IL编译成机器码,那么微软当然有办法根据平台的差异性编译出对应的机器码。
忽略不适应代码
1: if (numberOfCPUs > 1) {
2: ...
3: }
如果主机只有一个CPU,JIT编译器不会为上述代码生成任何CPU指令,那么这样顺带的结果就是最终的代码变得更小,执行的更快(可能有人说扯淡,就算一个CPU的这段代码也不会执行啊,那么大家得考虑机器码不是面向对象的语言可能一个小小的if就会顺带很多指令)。
未来还有更多
这种优化未来只会更多,因为CLR在不停的更新。。。
抛弃预编译吗?
答案肯定是否的,预编译有自己的优势,如果你所写的代码只在一台服务器或者少个数的服务器上运行,那么完全可以针对服务器进行预编译,但面向多服务端、客户端的程序还是最好采用JIT编译。
结语
部分引自:CLR via C#(第三版)
其实我觉得.NET并不是完全的编译型语言,从JIT编译来看他也是一种解析执行语言(把IL解析成机器语言)。
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,转载文章之后须在文章页面明显位置给出作者和原文连接,谢谢。欢迎大家关注微信号。扫下面的二维码或者收藏下面的二维码关注吧(长按下面的二维码图片、并选择识别图中的二维码)

【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验