代码之家  ›  专栏  ›  技术社区  ›  Richard Szalay

使用const局部变量有运行时的好处吗?

  •  43
  • Richard Szalay  · 技术社区  · 16 年前

    除了确保它们不能更改(根据编译器错误的调整)之外,JIT是否对常量局部变量进行了任何优化?

    如。

    public static int Main(string[] args)
    {
        const int timesToLoop = 50;
    
        for (int i=0; i<timesToLoop; i++)
        {
            // ...
        }
    }
    
    5 回复  |  直到 16 年前
        1
  •  84
  •   Darin Dimitrov    16 年前

    生成的IL不同(使用释放模式):

    using constant local                   using normal local
    ---------------------------------------------------------------------
    .entrypoint                            .entrypoint
    .maxstack 2                            .maxstack 2
    .locals init (                         .locals init (
        [0] int32 i)                           [0] int32 timesToLoop,
    L_0000: ldc.i4.0                           [1] int32 i)
    L_0001: stloc.0                        L_0000: ldc.i4.s 50 
    L_0002: br.s L_0008                    L_0002: stloc.0 
    L_0004: ldloc.0                        L_0003: ldc.i4.0  
    L_0005: ldc.i4.1                       L_0004: stloc.1 
    L_0006: add                            L_0005: br.s L_000b 
    L_0007: stloc.0                        L_0007: ldloc.1 
    L_0008: ldloc.0                        L_0008: ldc.i4.1 
    L_0009: ldc.i4.s 50                    L_0009: add
    L_000b: blt.s L_0004                   L_000a: stloc.1 
    L_000d: ret                            L_000b: ldloc.1 
                                           L_000c: ldloc.0 
                                           L_000d: blt.s L_0007
                                           L_000f: ret 
    

    正如您所见,编译器用常量的值替换所有变量用法,这将导致更小的堆栈。

        2
  •  14
  •   Tangiest    16 年前

    Snippet Compiler

        public static void Main()
        {
            DateTime datStart = DateTime.UtcNow;
            const int timesToLoop = 1000000;
    
            for (int i=0; i < timesToLoop; i++)
            {
                WL("Line Number " + i.ToString());
            }
    
            DateTime datEnd = DateTime.UtcNow;
            TimeSpan tsTimeTaken = datEnd - datStart;
            WL("Time Taken: " + tsTimeTaken.TotalSeconds);
            RL();
        }
    

    注意,WL和RL只是用于读取和写入控制台的辅助方法。

    const 关键词。结果令人惊讶:

                            Time Taken (average of 3 runs)
    
    Using const keyword         26.340s
    Without const keyword       28.276s
    

    我知道这是一个非常粗糙的'n'ready测试,但是 常数 关键字显示为有效的 micro-optimization

        3
  •  6
  •   Ahmad Mageed    14 年前

    您的代码(使用const)将实际编译为:

    public static int Main(string[] args){    
        for (int i=0; i < 50; i++)  
        {
    
        }
    }
    

    变量将编译为变量时:

    public static int Main(string[] args){
        int timesToLoop = 50;    
        for (int i=0; i < timesToLoop; i++)  
        {
    
        }
    }
    
        4
  •  4
  •   Paul Wade    12 年前

    这不是一个很好的答案,只是想分享一下这一点,但是本文没有明确提到运行时的好处:
    Coding Standard Rule #2: Use const Wherever Possible

    摘录:
    推理:尽可能多地使用const的好处是编译器强制保护,防止意外写入应为只读的数据。

        5
  •  0
  •   GraemeF    16 年前

    一个区别是,如果您有一个引用 const 字段,并且您后来更改了该值,则引用程序集在重新生成之前仍将使用旧值。