如何+ =更优化正常表达

时间:2014-04-29 11:05:57

标签: c# .net optimization

我在某处读到:

良好做法: exp += val 糟糕的做法: exp = exp + val

第二个选项强制JIT评估exp的两个副本,并且很多时候不需要这样做。第一个语句可以比第二个语句优化得更好,因为JIT可以避免两次评估exp。

所以我写了一个示例测试来验证这一点。但我得到的结果是我能得出结论。任何人都可以帮助我理解上面的一个是好的还是坏的做法,或者我的例子中有任何错误。

        static void Main(string[] args)
    {
        DateTime startTime;
        DateTime endTime;

        for (int run = 0; run < 10; run++)
        {
            Console.WriteLine("--- Run #" + run.ToString());
            long sumB = 0;
            startTime = DateTime.Now;
            for (long i = 0; i < 1000000000; i++)
            {
                sumB = sumB + 2L;
            }
            endTime = DateTime.Now;
            Console.WriteLine(endTime - startTime);

            long sumA = 0;
            startTime = DateTime.Now;
            for (long j = 0; j < 1000000000; j++)
            {
                sumA += 2L;
            }
            endTime = DateTime.Now;
            Console.WriteLine(endTime - startTime);
        }

        Console.WriteLine("*");
        Console.ReadKey();
    }

2 个答案:

答案 0 :(得分:5)

至少在C ++中(我不知道C#),a += b只会评估a一次,而a = a + b会评估两次。

如果它是一个复杂的表达,那么这可能会对性能产生影响。如果像在你的例子中那样,它是一个简单的变量(或者更一般地说,是一个编译器可以证明没有副作用的表达式),那么两者都应该被优化以产生相同的代码,所以那里有#s; s可能没有显着差异。

更好的建议是支持a += b,因为它可以避免冗余,帮助提高可读性并减少错误的范围,而不是使用(通常是假的或不相关的)关于性能的论据。

答案 1 :(得分:2)

a += b

仅在

时评估每个表达式一次
a = a + b

评估两次。 a可能是一个昂贵的表达式(不是局部变量):

int[] GetArray() { return new int[100000]; }

GetArray()[0] += 1;

非常不同
GetArray()[0] = GetArray()[0] + 1;

并且在这种情况下在语义上不同,但这不是重点。假设GetArray很贵。


这是一种罕见的情况,我只是说,因为你问的是性能。通常情况下,您只是出于文体学原因而写出复合作业表格,这是主观的。


为了好玩,我们可以深入了解该数组示例的工作原理。 C#编译器将发出IL,用于计算给定数组元素的托管指针(&#34;内部指针&#34;),然后它将评估右侧,它使用指针将结果存储到数组中。

令人惊讶的是,在IL级别,托管指针很常见。 C#使你屏蔽它。