【问题标题】:Performance penalty for using 'unnecessary' local variable in C#?在 C# 中使用“不必要的”局部变量的性能损失?
【发布时间】:2016-03-17 15:51:31
【问题描述】:

使用额外的局部变量来存储方法的结果是否会降低性能?

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/

【问题讨论】:

  • 我不这么认为。因为在这种情况下,它应该被优化掉。最简单的检查方法是双向编写并比较生成的 IL。
  • 如果你看一下 IL 你就会知道编译器做了什么。
  • 即使有,也很难看出这种差异。与string.Format 本身相比,它完全相形见绌,一方面:) 在考虑潜在的性能问题时,您需要牢记观点。
  • “我还没有实际测试过这个代码示例”:也许你应该。
  • 如果要查看函数返回的值,请在右大括号上放置一个断点。 VS显示返回值。

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


【解决方案1】:

通常没有速度差异。参见例如http://goo.gl/b9856yhttp://goo.gl/WfIhmT

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

在调试模式下,IL 代码稍长一些(因为存储到局部变量是显式的):http://goo.gl/KCkORV

【讨论】:

  • 这仅对新的 Roslyn 编译器有效。
【解决方案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        

这两个额外的调用会不会是性能问题,不太可能,但我很难说我不知道​​这个区域有多重要。

【讨论】:

  • 如果您的方法每秒被调用 200 次(它可能是服务调用的一部分),那么这很重要。
猜你喜欢
  • 1970-01-01
  • 2012-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-17
  • 1970-01-01
相关资源
最近更新 更多