众所周知.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解析成机器语言)。

在.net中为什么第一次执行会慢?的更多相关文章

  1. 人机大战中AlphaGo及其执子人黄士杰

    2016年3月9日注定要写入围棋界的历史.IT界的历史以及科学界的历史.当天,韩国著名围棋棋手李世石VS谷歌AlphaGo的人机大战赛在韩国首尔举行.对弈的一方为拥有1200多个处理器的谷歌人工智能系 ...

  2. 解决Spring Cloud中Feign第一次请求失败的问题

    在Spring Cloud中,Feign和Ribbon在整合了Hystrix后,可能会出现首次调用失败的问题 com.netflix.hystrix.exception.HystrixTimeoutE ...

  3. shell 脚本中 while 只执行一次

    实例代码 while read line ; do ssh -p20002 $line -o StrictHostKeyChecking=no xxxxxxxxx done < ip.txt w ...

  4. 【跨域】SpringBoot跨域,拦截器中,第一次获取的请求头为NULL,发送两次请求的处理方式

    背景: 在做前后端分离时,牵扯到跨域,但是已经设置了跨域 前端设置了允许携带Cookie axios.defaults.withCredentials = true; 后端也配置了跨域 浏览器端查看发 ...

  5. Scala中Iterator允许执行一次

    背景 使用spark执行mapPartitionsWithIndex((index,iterator)=>{....}),在执行体中将iterator进行一次迭代后,再次根据iterator执行 ...

  6. 在内网中OWA第一次访问速度慢的问题

      当网络环境为内网时,有时访问OWA站点一直卡在Office Web App 那里. 这是因为SharePoint有一个证书需要联网检索 此环境为SharePoint 2013 通过下面的三个步骤 ...

  7. Crontab中shell每分钟执行一次HDFS文件上传不执行的解决方案

    一.Crontab -e 加入输出Log */1 * * * * /qiwen_list/upload_to_hdfs.sh > /qiwen_list/mapred.log 2>& ...

  8. Unity中让Update中的方法执行一次

    Unity中让Update中的方法执行一次 Unity中,很多时候,代码需要放在Update中时刻监测状态,一旦状态符合,又只需要代码执行一次:其实可以通过设置控制量的方式,让代码只执行一次:方法:设 ...

  9. 小tips:JS中this操作执行像(object.getName = object.getName)()操作改变了this

    var name = "The window"; var object = { name: "My Object", getName: function(){ ...

随机推荐

  1. SQL2008 提示评估期已过的解决方法

    提示窗口: 解决步骤: 第一步:进入SQL2008配置工具中的安装中心 第二步:再进入维护界面,选择版本升级 第三步:进入产品密钥,输入密钥 第四步:一直点下一步,直到升级完毕. SQL Server ...

  2. luluzero的angularJs学习之路_angularJs示例代码

    最近开始自学 angularJs这个前端MVC框架,感觉在前端实现MVC很酷有木有.哈哈哈... 先说说我对前端MVC的一个基本的理解吧(刚开始学习接触得还比较浅显,理解可能会有些不到位,还请各位大神 ...

  3. C++ new(3)

    转载自:http://www.builder.com.cn/2008/0104/696370.shtml “new”是C++的一个关键字,同时也是操作符.关于new的话题非常多,因为它确实比较复杂,也 ...

  4. Cassandra 分布式集群

    1 实施Cassandra集群,并验证集群功能正常,抓图实验过程 2 为什么说对于布隆过滤器有"确定某个元素是否在某个集合中的代价和总的元素数目无关"?误判率和元素数目有关吗?为什 ...

  5. [转]JavaScript实现 页面滚动图片加载

    本文转自:http://www.cnblogs.com/Darren_code/archive/2011/07/21/LoadImage.html 又到了这个月的博客时间了,原计划是打算在这个月做一个 ...

  6. Unity3D 实现简单的语音聊天 [iOS版本]

    现在很多手机游戏中的聊天系统都加入语音聊天的功能,相比于传统的文字聊天,语音聊天在MMORPG中显得尤为重要,毕竟直接口头交流总比你码字快得多了,也更直观些. 实现语音聊天的方法很多,U3D中有不少第 ...

  7. 【读书笔记《Android游戏编程之从零开始》】7.Android 游戏开发常用的系统控件(Dialog)

    在Android应用开发中,Dialog(对话框)创建简单且易于管理因而经常用到,对话框默认样式类似创建样式的Activity.首先介绍android.app.AlertDialog下的Builder ...

  8. 如何实现ZBrush中的Alt和Shift键的快速运用

    ZBrush是一个数字雕刻和绘画软件,它以强大的功能和直观的工作流程彻底改变了整个三维雕刻行业.在一个简洁的界面中,ZBrush®为当代数字艺术家提供了世界上最先进的工具.利用快捷键能使操作更快捷高效 ...

  9. leetcode-Single Number III 找独数

    Single Number III Given an array of numbers nums, in which exactly two elements appear only once and ...

  10. 第50课 C++对象模型分析(上)

    1. 回归本质 (1)class是一种特殊的结构体 ①在内存中class依旧可以看作变量的集合 ②class与struct遵循相同的内存对齐规则 ③class中的成员函数与成员变量是分开存放的.即每个 ...