zoukankan      html  css  js  c++  java
  • C# 编译器对局部变量的优化

    C# 编译器对局部变量的优化

    C# 的编译器可以对代码进行优化,所以,我们在写代码的时候,可以更多地考虑一下代码的易读性问题。

    不考虑基本的对齐和换行美化。看一下局部变量优化问题。

    C# 示例代码

    例如,我们有一段如下的代码:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ConsoleApp1
    {
        class Program
        {
            static void Main(string[] args)
            { 
                var s = DoSomething();
                Console.WriteLine(s);
            }
    
            static string DoSomething()
            {
                var s1 = "Hello, world.";
                var s2 = s1.ToUpper();
                return s2;
            }
        }
    }
    

    在 DoSomething() 这个方法中,里面定义了两个局部变量:

    • s1
    • s2

    在 Main() 方法中,定义了一个局部变量:

    • s

    定义 s1 和 s2 是为了提高代码的可读性,它们会导致生成冗余的代码,降低执行效率吗?

    我们分别在 Debug 模式下和 Release 模式下进行编译,使用 ILDasm 查看生成的中间代码。

    Debug 模式下生成的中间代码

    在 Debug 下编译之后,DoSomething() 生成的中间代码如下,可以看到实际上有 3 个局部变量。除了我们自己定义的 s1 和 s2 之外,还有一个生成的 V_2,代码的尺寸为 20。

    .method private hidebysig static string  DoSomething() cil managed
    {
      // Code size       20 (0x14)
      .maxstack  1
      .locals init ([0] string s1,
               [1] string s2,
               [2] string V_2)
      IL_0000:  nop
      IL_0001:  ldstr      "Hello, world."
      IL_0006:  stloc.0
      IL_0007:  ldloc.0
      IL_0008:  callvirt   instance string [mscorlib]System.String::ToUpper()
      IL_000d:  stloc.1
      IL_000e:  ldloc.1
      IL_000f:  stloc.2
      IL_0010:  br.s       IL_0012
      IL_0012:  ldloc.2
      IL_0013:  ret
    } // end of method Program::DoSomething
    

    看一下 Main() 方法。

    有我们定义的 s 这一个局部变量,代码尺寸为 15 个字节。

    .method private hidebysig static void  Main(string[] args) cil managed
    {
      .entrypoint
      // Code size       15 (0xf)
      .maxstack  1
      .locals init ([0] string s)
      IL_0000:  nop
      IL_0001:  call       string ConsoleApp1.Program::DoSomething()
      IL_0006:  stloc.0
      IL_0007:  ldloc.0
      IL_0008:  call       void [mscorlib]System.Console::WriteLine(string)
      IL_000d:  nop
      IL_000e:  ret
    } // end of method Program::Main
    

    Release 模式下生成的中间代码

    而在 Release 模式下,实际上,DoSomething() 中所有的局部变量都被优化掉了。代码尺寸也只有 11 个字节。

    .method private hidebysig static string  DoSomething() cil managed
    {
      // Code size       11 (0xb)
      .maxstack  8
      IL_0000:  ldstr      "Hello, world."
      IL_0005:  callvirt   instance string [mscorlib]System.String::ToUpper()
      IL_000a:  ret
    } // end of method Program::DoSomething
    

    还可以看一下 Main() 方法,这个局部变量 s 也被优化掉了。代码尺寸也只有 11 字节了。

    .method private hidebysig static void  Main(string[] args) cil managed
    {
      .entrypoint
      // Code size       11 (0xb)
      .maxstack  8
      IL_0000:  call       string ConsoleApp1.Program::DoSomething()
      IL_0005:  call       void [mscorlib]System.Console::WriteLine(string)
      IL_000a:  ret
    } // end of method Program::Main
    

    结论

    编译器会尽可能对代码进行优化,我们可以为了提高代码的易读性增加一些局部变量,这并不会导致生成冗余代码并导致执行性能的下降。

  • 相关阅读:
    DGA域名可以是色情网站域名
    使用cloudflare加速你的网站隐藏你的网站IP
    167. Two Sum II
    leetcode 563. Binary Tree Tilt
    python 多线程
    leetcode 404. Sum of Left Leaves
    leetcode 100. Same Tree
    leetcode 383. Ransom Note
    leetcode 122. Best Time to Buy and Sell Stock II
    天津Uber优步司机奖励政策(12月28日到12月29日)
  • 原文地址:https://www.cnblogs.com/haogj/p/13889976.html
Copyright © 2011-2022 走看看