在C#中,++ i与i + = 1有任何性能差异吗?

时间:2011-07-31 13:05:30

标签: c# performance increment

i + = a应等于i = i + a。 在a == 1的情况下,这被认为效率低于++ i,因为它涉及更多的内存访问;或编译器是否与++ i完全相同?

5 个答案:

答案 0 :(得分:12)

很容易回答:C#编译器将C#源代码转换为IL操作码。没有专用的IL操作码执行与++运算符等效的操作。如果您使用ildasm.exe工具查看生成的IL,这很容易看到。此示例C#片段:

        int ix = 0;
        ix++;
        ix = ix + 1;

生成:

  IL_0000:  ldc.i4.0               // load 0
  IL_0001:  stloc.0                // ix = 0

  IL_0002:  ldloc.0                // load ix
  IL_0003:  ldc.i4.1               // load 1
  IL_0004:  add                    // ix + 1
  IL_0005:  stloc.0                // ix = ix + 1

  IL_0006:  ldloc.0                // load ix
  IL_0007:  ldc.i4.1               // load 1
  IL_0008:  add                    // ix + 1
  IL_0009:  stloc.0                // ix = ix + 1

它生成完全相同的代码。抖动无法做任何事情,只能生成同样快速的机器代码。

前/后增量运算符是C#中的语法糖,只要它使代码更清晰,就可以使用它。或者更相关:避免它使它更少清晰可辨。他们确实有诀窍让你创造出有太多副作用的表情。

答案 1 :(得分:4)

编译器应该以你编写的方式优化代码,所以我相信i = i + 1与++ i相同。

答案 2 :(得分:2)

我不认为会有任何不同,但你可以把它付诸行动,例如:

class Program
{
    static void Main(string[] args)
    {
        //Add values
        List<objClass> lst1 = new List<objClass>();
        for (int i = 0; i < 9000000; i++)
        {
            lst1.Add(new objClass("1", ""));
        }

        //For loop ++i
        DateTime startTime = DateTime.Now;
        for (int i = 0; i < 9000000; ++i)
        {
            lst1[i]._s1 = lst1[i]._s2;
        }
        Console.WriteLine((DateTime.Now - startTime).ToString());

        //For loop i+=1
        startTime = DateTime.Now;
        for (int i = 0; i < 9000000; i+=1)
        {
            lst1[i]._s1 = lst1[i]._s2;
        }
        Console.WriteLine((DateTime.Now - startTime).ToString());

    }
public class objClass
    {
        public string _s1 { get; set; }
        public string _s2 { get; set; }

        public objClass(string _s1, string _s2)
        {
            this._s1 = _s1;
            this._s2 = _s2;
        }
    }

}

答案 3 :(得分:1)

这取决于。理论上,给定一个足够天真的编译器,++x可能比x += 1更有效。

但是,我不知道这种天真的编译器。

  • 如果在编译时知道操作数的值,则编译器可以优化操作。
  • 如果可以确定该值在运行时是常量,那么JIT编译器也可以优化操作。

此外,现代CPU是高度复杂的野兽,可以并行执行大量操作,而且通常,通过与更大,更复杂的并行运行它们,可以完全隐藏这些“简单”操作。

一个好的经验法则,在优化时,一般写作时,尽可能清楚地表达你的意图

这使得其他程序员更容易阅读您的代码,但使编译器更容易这样做。

如果要增加值,请使用增量运算符(++),因为它准确描述了您要执行的操作。

如果您想添加变量或未知值,请使用+=运算符,因为就是它的

如果您清楚自己的意图,那么编译器会获得有关您的代码的更多信息,并可以相应地进行优化。

如果你写x += 1,你真的试图让编译器绊倒。您正在说“使用通用添加运算符将{1}}添加一个”。然后编译器必须弄清楚“好吧,你使用通用添加,但我可以看到这是必要的,所以我只是要增加”。你可以告诉它。相反,现在你必须依赖编译器聪明。

答案 4 :(得分:0)

除非定义了一个const int == 1编译器如何在编译时知道a == 1?

所以答案必须是否定的,编译器无法将其编译为++ i。