使用'不必要的' C#中的局部变量?

时间:2016-03-17 15:51:32

标签: c# performance compiler-optimization local-variables

使用额外的局部变量来存储方法的结果会导致性能下降吗?

public string void ToFunkyDutchDate(DateTime this theDate) {
    var result = string.Format("{0:dd-MM-yyyy}", theDate);
    return result;
}

在类似的琐碎案例中,我甚至可以立即返回格式化的字符串。但这仅仅是一个简单的例子,因为在一些更复杂的功能中,我经常使用这个'技巧'首先将结果分配给临时局部变量。

我的主要原因是这样可以更轻松地进行调试。我可以在return result;行上设置断点,运行并检查我的函数出现的结果是否正确。

但额外的临时result变量仍然感觉有点像无法使用的替代品而没有:"

public static string ToFunkyDutchDate(DateTime this theDate) {
    return string.Format("{0:dd-MM-yyyy}", theDate);
}

我已经通过三种方式缓解了这种唠叨的感觉:

  • 任何表现下降都可以忽略不计
  • 拥有像result这样的变量会使代码比return very long multi-line expression更易读,这会使性能下降更糟糕
  • 如果C-sharp的编译器在任何地方都是不错的 - 我认为它是 - 那么它应该编译额外的变量。例如。使得结果字节码与函数刚刚返回计算结果而不使用临时变量完全相同。立即(当不在调试模式下运行时) - 或者可能在进行优化/生成构建时(/optimize+)。

但是我已经这么做了很多年了,在如此多的代码行中,我想我最终还是会问它。这里的任何编译器向导都知道吗? :)

编辑:一分钟内回答一个已经酝酿多年的问题。 Stackoverflow有多棒。伟大的工具:http://tryroslyn.azurewebsites.net/

2 个答案:

答案 0 :(得分:10)

通常没有速度差异。例如,请参阅lapack's referencehttp://goo.gl/b9856y

两个版本的代码在发布模式下生成相同的IL代码。

在调试模式下,IL代码会稍长一些(因为本地变量的存储是显式的):http://goo.gl/WfIhmT

答案 1 :(得分:2)

我刚刚通过 LinqPad 运行这两种方法,并查看它提供的IL更改了两条指令:

使用未使用的变量:

IL_0000:  ldstr       "{0:dd-MM-yyyy}"
IL_0005:  ldarg.0     
IL_0006:  box         System.DateTime
IL_000B:  call        System.String.Format
IL_0010:  stloc.0     // result
IL_0011:  ldloc.0     // result
IL_0012:  ret         

直接返回string.Format的结果:

IL_0000:  ldstr       "{0:dd-MM-yyyy}"
IL_0005:  ldarg.0     
IL_0006:  box         System.DateTime
IL_000B:  call        System.String.Format
IL_0010:  ret        

这两个额外的电话会不会成为性能问题,但我很难说我不知道​​这个区域有多重要。