【发布时间】:2011-06-12 16:47:16
【问题描述】:
让我们比较两段代码:
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:调用 void [mscorlib]System.Console::WriteLine(string)
IL_000e:返回
第二个示例代码 IL:
.maxstack 1
.locals init ([0] string str)
IL_0000: ldstr "测试"
IL_0005: stloc.0
IL_0006: ldloc.0
IL_0007:调用 void [mscorlib]System.Console::WriteLine(string)
IL_000c:返回
可能这段代码是由 JIT 编译器优化的吗? 那么用null初始化局部bethod变量是否会影响性能(我知道这是非常简单的操作,但无论如何)我们应该避免它吗? 先谢谢了。
【问题讨论】:
-
通常认为用一个永远不会使用的值进行初始化是不好的形式,仅仅是因为它增加了混乱(分配了一个对逻辑没有意义的“null”。)任何相关的性能命中可以忽略不计;前一个原因是避免它的更有说服力的原因。
-
@Dan Bryany:感谢您的评论。我同意你的观点,我们不应该使用 null 进行初始化,但一些开发人员更喜欢使用它来直接显示初始化。我的团队中有这样的人:)
-
通常我宁愿在变量被初始化之前甚至不声明变量,因为这进一步限制了尝试理解代码时的概念范围(即本地变量尽可能地位于它们被使用的地方。 ) 这种方法的副作用是,随着方法的增长,局部变量的放置倾向于突出代码中可以提取新方法的区域。
-
@Jason:这不是一个很好的例子 - 'line' 绝对可以在循环体内限定范围。
-
@Andrew Medico:你太客气了,这是一个糟糕的例子,这显然是我的迟钝。这是一个更好的例子:
string value; if(!dictionary.TryGetValue(key, out value)) { // something }.
标签: c# performance initialization jit il