使用null初始化局部变量会影响性能吗?

时间:2011-01-20 19:24:05

标签: c# performance initialization jit il

让我们比较两段代码:

String str = null;
//Possibly do something...
str = "Test";
Console.WriteLine(str);

String str;
//Possibly do something...
str = "Test";
Console.WriteLine(str);

我一直在想这些代码是平等的。但是在我构建这些代码(检查了优化的发布模式)并比较生成的IL方法后,我注意到第一个样本中还有两个IL指令:

第一个示例代码IL:

.maxstack 1
  .locals init([0] string str)
   IL_0000:ldnull
  IL_0001:stloc.0
  IL_0002:ldstr“测试”
  IL_0007:stloc.0
  IL_0008:ldloc.0
  IL_0009:call void [mscorlib] System.Console :: WriteLine(string)
  IL_000e:ret

第二个示例代码IL:

.maxstack 1
  .locals init([0] string str)
  IL_0000:ldstr“测试”
  IL_0005:stloc.0
  IL_0006:ldloc.0
  IL_0007:call void [mscorlib] System.Console :: WriteLine(string)
  IL_000c:ret

可能这个代码是由JIT compiller优化的? 那么带有null的本地bethod变量的初始化会影响性能(我知道这是非常简单的操作,但无论如何)我们应该避免它吗? 先谢谢。

3 个答案:

答案 0 :(得分:7)

http://www.codinghorror.com/blog/2005/07/for-best-results-dont-initialize-variables.html

总结一下这篇文章,在运行各种基准测试之后,将对象初始化为一个值(作为定义的一部分,在类的构造函数中,或作为初始化方法的一部分)可以是大约10-35在.NET 1.1和2.0上慢了%。较新的编译器可以优化定义的初始化。本文最后建议避免初始化作为一般规则。

答案 1 :(得分:6)

正如Jon.Stromer.Galley的链接指出的那样,它稍微慢一点。但差异非常小;可能是纳秒的顺序。在那个级别,使用像C#这样的高级语言的开销使任何性能差异都相形见绌。如果性能是一个很大的问题,你也可以用C或ASM或其他东西进行编码。

编写清晰代码(无论对您意味着什么)的价值远远超过成本与收益方面的0.00001ms性能提升。这就是为什么首先存在C#和其他高级语言的原因。

我认为这可能是一个学术问题,我并不打算理解CLR内部的价值。但在这种情况下,重点关注似乎是错误的。

答案 2 :(得分:0)

今天(2019年),. NET Framework和.NET Core 编译器都足够聪明,可以优化不必要的初始化。 (以及无用的stloc.0-ldloc.0对。)

两个版本都编译为

        .maxstack 8

        ldstr "Test"
        call void [System.Console]System.Console::WriteLine(string)
        ret

请参阅我的SharpLab experiment作为参考。

但是当然实现会发生变化,但是贾斯汀的答案是永恒的:我出于好奇而进行了此实验,在实际情况下,我专注于代码的清晰性和表达性,而忽略了微优化。