【问题标题】:Is a += 5 faster than a = a + 5?a += 5 比 a = a + 5 快吗?
【发布时间】:2013-11-16 15:25:27
【问题描述】:

我目前正在学习 C# 中的运算符和表达式,我知道如果我想将变量的值增加 5,我可以通过两种不同的方式来实现:a = a + 5a += 5。显然,第二种方式写起来更容易、更快,读起来也更愉快。但是,在计算机方面,a += 5 是否比 a = a + 5 快?与较长版本的表达式相比,编译和执行所需的时间是否更少?

【问题讨论】:

  • 只是syntactic sugar
  • 如果这是您代码中最大的性能问题,那么您做得很好。继续。实现更多有用的功能。
  • “我目前正在学习 [..] C#” - 那么您不必担心性能问题,尤其是那些低级问题。如果您真的担心这些最基本表达式的性能,请对它们进行基准测试。
  • 鉴于您想深入了解内部情况,我建议您使用 .NET 反编译器并检查生成的字节码。只需搜索“Free .NET Decompiler”,您就会得到几个选项。
  • @wdosanjos 对于像这样的低级问题(尽管可能不是专门针对这种情况),字节码可能会产生误导,您应该查看 JIT 编译的代码。

标签: c# operators expression


【解决方案1】:

但是,在计算机方面,a += 5 比 a = a + 5 快吗?

两者相同,第一个(a += 5) 等于第二个a = a + 5

你可能会看到:

+= Operator (C# Reference)

使用+= 赋值运算符的表达式,例如x += y 是 等价于x = x + y 除了 x 只计算一次。 + 运算符的含义取决于 x 和 y 的类型 (数字操作数的添加,字符串操作数的连接,以及 等等)。

所以它取决于a 的类型,并且在多个线程访问您的变量a 的情况下,您可能会得到不同的结果。但对于大多数其他情况,它是相同的:

代码:

static void Main(string[] args)
{
    int a = 10;
    a += 5;
    Console.WriteLine(a);
}

IL 是在发布模式下构建

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       14 (0xe)
  .maxstack  2
  .locals init ([0] int32 a)
  IL_0000:  ldc.i4.s   10
  IL_0002:  stloc.0
  IL_0003:  ldloc.0
  IL_0004:  ldc.i4.5
  IL_0005:  add
  IL_0006:  stloc.0
  IL_0007:  ldloc.0
  IL_0008:  call       void [mscorlib]System.Console::WriteLine(int32)
  IL_000d:  ret
} // end of method Program::Main

通过代码生成相同的IL:

static void Main(string[] args)
{
    int a = 10;
    a = a + 5;
    Console.WriteLine(a);
}

IL(相同)是:

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       14 (0xe)
  .maxstack  2
  .locals init ([0] int32 a)
  IL_0000:  ldc.i4.s   10
  IL_0002:  stloc.0
  IL_0003:  ldloc.0
  IL_0004:  ldc.i4.5
  IL_0005:  add
  IL_0006:  stloc.0
  IL_0007:  ldloc.0
  IL_0008:  call       void [mscorlib]System.Console::WriteLine(int32)
  IL_000d:  ret
} // end of method Program::Main

【讨论】:

  • 如果被翻译了,会不会慢很多?
  • @SuperPrograman 它由编译器进行翻译,因此该翻译没有运行时开销。
  • @SuperPrograman,slower 只应在执行时考虑。所以在执行时没关系,它已经编译好了。
  • @Habib 错了。两者虽然相似,但并不等价。
  • @Habib 这取决于a 是什么。
【解决方案2】:

这取决于a 是什么。 a = a + 5 评估 a 两次。 a += 5 精确评估 a 一次

如果a 是一个整数,那么这种差异在大多数 情况下可能并不重要,尽管严格来说并非所有 情况。例如,如果从多个线程访问 a,那么竞争条件的确切类型和窗口可能会有所不同。

最重要的是,如果评估表达式会导致副作用,那么这就是观察到一次与观察到两次的副作用之间的差异。在某些情况下,这可能是一个交易,可能会影响代码的正确性,而不仅仅是它的速度。

【讨论】:

    猜你喜欢
    • 2020-05-03
    • 2012-09-10
    • 1970-01-01
    • 2018-09-10
    • 2014-11-05
    • 2017-11-21
    • 1970-01-01
    • 1970-01-01
    • 2014-07-28
    相关资源
    最近更新 更多