代码的优化

在VS中,有两个编译器开关会影响生成的代码的优化:

    一个是在项目属性->生成->优化代码选项,如果没有选中该选项,则生成的IL代码是没有经过优化的,在IL文件中会包含很多NOP指令,这些指令是空操作指令,作用是方便设置断点,在流程控制指令后边都会添加NOP指令,对于下面的简单代码:

static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            if (true)
            {
                Console.WriteLine("123");
            }
        }
    }

如果没有经过优化,生成的IL代码是:

.method private hidebysig static void  Main() cil managed
{
  .entrypoint
  .custom instance void [mscorlib]System.STAThreadAttribute::.ctor() = ( 01 00 00 00 ) 
  // 代码大小       17 (0x11)
  .maxstack  1
  .locals init ([0] bool CS$4$0000)
  IL_0000:  nop
  IL_0001:  ldc.i4.0
  IL_0002:  stloc.0
  IL_0003:  nop
  IL_0004:  ldstr      "123"
  IL_0009:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_000e:  nop
  IL_000f:  nop
  IL_0010:  ret
} // end of method Program::Main

如果选中了优化代码选项,则不会添加NOP指令,则调试的时候没法在流程控制指令(while、if、try、catch等等)上添加端点,对单步调试带来很大困难。但是经过优化的代码是文件变得更小。经过优化后,生成的代码如下:

.method private hidebysig static void  Main() cil managed
{
  .entrypoint
  .custom instance void [mscorlib]System.STAThreadAttribute::.ctor() = ( 01 00 00 00 ) 
  // 代码大小       11 (0xb)
  .maxstack  8
  IL_0000:  ldstr      "123"
  IL_0005:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_000a:  ret
} // end of method Program::Main

在VS中默认新建一个工程,debug模式是不会进行优化代码的而release模式默认是进行优化代码的,所以我们在写代码的过程中最好使用debug模式,在发布时最好使用release模式。

    另外一个属性是在生成->高级里边的调试信息,对于C#而言,该选项一共有三个,none、pdbonly和full。None选项是最少使用的一个,在vs的默认设置中是不需要设置这个的,因为none和pdbonly就性能来说没有任何的不同,并且pdbonly还有独有的优势,这个优势下面马上进行说明。之所以会出现none选项是因为在.NET 1.0的时候他们确实是有区别的。具体信息读者可以查相关文档。

    接下来要说的是pdbonly和full,默认VS在debug模式下会设置为full,在release下设置为pdbonly。如果设置成pdbonly,build的时候会生成pdb文件。这个pdb文件中包含IL指令到源代码之间的映射,这个映射可以使得程序在release下运行并且能够进行调试(不是跟进程,而是直接在vs启动),如果我们通过调试-->窗口-->模块观察,可以看到这个时候程序是去加载符号文件的,所以才能够获取断点。

2967261160

但是pdbonly不能跟进程进行调试,这也是pdbonly和full的主要区别,在生成程序集的时候,有一个属性debuggableAttribute,这个属性标识符号文件会不会连接调试器,full下是true,pdbonly是false,所以我们在通过调试-->窗口-->模块观察,pbdonly程序通过跟进程调试,这个时候程序是跳过符号文件的。

4018730828

原文地址:https://www.cnblogs.com/sauronKing/p/4746152.html