• 五、CLR加载程序集代码时,JIT编译器对性能的产生的影响


    1、CLR首次加载代码造成的性能损失     

     四、CLR执行程序集中代码介绍了CLR在首次执行一个类的时,会初始化一个内部结构,然后当目标方法被首次调用时,JITComplier函数(JIT编译器)会验证IL代码并将IL代码编译成本地CPU指令并存储到动态内存中,这意味着一旦应用程序终止,编译好的代码也会被丢弃,所以,当再次运行应用程序,或者同时启动应用程序的两个实例(使用两个不同的操作系统的进程),JIT编译器必须再次将IL编译成本机指令.对于某些应用程序,这可能会增加内存的负担.

    相比之下,本机(native)应用程序的只读代码页可由应用程序正在运行的所有实例共享.

    2、CLR首次加载代码造成的性能损失的严重程度

    对于大多数应用程序,JIT编译造成的损失并不严重,大多数应用程序都在反复的调用相同的方法。应用程序运行期间,这些方法只会对性能造成一次性的影响.除此之外,在方法内部花费的时间可能比花在首次调用方法,JIT编译和优化IL所花费的时间更多.

    3、CLR加载代码时JIT编译器进行的代码优化

    CLR首次加载程序集代码时,JIT将IL编译成本地代码时,会对其进行代码优化,这类似与非托管C++编译器的后端所做的事情.这可能也会花费加多的时间生成优化代码.

    (1)、编译器开关/optimize和/debug对代码的影响

    /optimize开关:

    C#编译器生成的未优化IL代码,将包含许多NOP(空操作)指令,还将包含许多跳转到下一行代码的分支指令.Visual Stdio利用这些指令在调试提供"编辑并继续"功能.另外,利用这些额外的指令,还可在控制流程指令(比如for,while,do,if,else,try,catch和finally)上设置断点,使代码更容易调试.相反,如果生成优化的IL代码,C#编译器会删除多余的NOP和分支指令,而在控制流程被优化之后,代码就不能再调试器中进行单步调试了。代码若在调试器中执行,一些函数求值可能无法进行.但是,优化过的IL代码变得更小,结果EXE/DLL文件也更小.

    /debug(+/full/pdbonly)开关:

    编译器会生成Program Database(PDB)文件,PDB文件帮助调试器查找局部变量并将IL指令映射到源代码.

    /debug:full开关告诉JIT编译器你打算调试程序集,那么JIT编译器会记录每条IL指令所生成的本机代码.这样依赖,就可利用Visual Studio的“即时”调试功能,将调试器连接到正在运行的进程,并方便地对源代码进行调试.

    不打开/debug:full开关,JIT编译器默认不记录IL与本机代码的联系,这使JIT编译器运行的稍快,占用内存也稍少.如果进程用Visual Stdio的“即时”调试功能,会强迫JIT编译器记录IL与本机代码的联系(无论编译器的开关设置是什么)除非在Visual Stdio中关闭了"在模块加载时取消JIT优化(权限托管)"操作步骤如下:

    工具-选项-调试

    (2)、Visual Stdio中新建C#项目时,编译器开关的默认设置

    通过VS新建项目时,项目的调试(Debug)配置的是/optimize-和debug:full开关(IL代码和本地代码均未优化-方便调试),而"发布"(Release)配置置顶的是/optimize+和/debug:pdbpnly开关(IL代码和本地代码均优化-文件变小,占用内存小)

  • 相关阅读:
    读书笔记——吴军《态度》
    JZYZOJ1237 教授的测试 dfs
    NOI1999 JZYZOJ1289 棋盘分割 dp 方差的数学结论
    [JZYZOJ 1288][洛谷 1005] NOIP2007 矩阵取数 dp 高精度
    POJ 3904 JZYZOJ 1202 Sky Code 莫比乌斯反演 组合数
    POJ2157 Check the difficulty of problems 概率DP
    HDU3853 LOOPS 期望DP 简单
    Codeforces 148D. Bag of mice 概率dp
    POJ3071 Football 概率DP 简单
    HDU4405 Aeroplane chess 飞行棋 期望dp 简单
  • 原文地址:https://www.cnblogs.com/GreenLeaves/p/8400567.html
Copyright © 2020-2023  润新知