Linq造成的性能损失

时间:2014-05-15 18:43:05

标签: c# performance linq foreach

最近的更新导致我的代码性能显着下降。通过使用剖析器,我发现损失是由使用Linq的一条线引起的。我做了一些测试,发现Linq比foreach慢得多。

        List<int> numbers = new List<int>();
        for (int i = 0; i < 1000; ++i)
            numbers.Add(i);
        var stopWatch = new Stopwatch();

        {
            int total = 0;
            for (int i = 0; i < 1000; ++i)
                total += i;
        }
        stopWatch.Start();
        for (int j = 0; j < 1000000; ++j)
        {
            int total = 0;
            for (int i = 0; i < 1000; ++i)
                total += i;
        }
        stopWatch.Stop();
        Console.WriteLine("Benchmark run time: {0}", stopWatch.ElapsedMilliseconds);

        {
            int total = 0;
            foreach (int i in numbers)
                total += i;
        }
        stopWatch.Restart();
        for (int j = 0; j < 1000000; ++j)
        {
            int total = 0;
            foreach (int i in numbers)
                total += i;
        }
        stopWatch.Stop();
        Console.WriteLine("foreach run time: {0}", stopWatch.ElapsedMilliseconds);

        {
            int total = 0;
            total += numbers.Sum();
        }
        stopWatch.Restart();
        for (int j = 0; j < 1000000; ++j)
        {
            int total = 0;
            total += numbers.Sum();
        }
        stopWatch.Stop();
        Console.WriteLine("Sum run time: {0}", stopWatch.ElapsedMilliseconds);

输出:

  

基准运行时间:653   foreach运行时间:3862   总运行时间:10233

这是否意味着我们应该始终避免在性能关键部分使用Linq?

更新: 修正了秒表未重置的错误 在为JIT启动秒表之前,每次测试一次 是的,这是在发布模式,没有调试

3 个答案:

答案 0 :(得分:7)

你忘了在foreach之后重置秒表

答案 1 :(得分:7)

  1. 再次启动之前调用stopWatch.Reset()。否则你的性能测试毫无价值 - 你总结了所有的结果。

  2. 您是否在Visual Studio之外的Release版本上运行测试?

  3. 是的,LINQ没有for循环那么快。但它更易读,写得更快。

答案 2 :(得分:3)

你的测试可能存在缺陷,根据MSDN你需要在每次使用后重置你的秒表。

话虽这么说,LINQ可能会变慢,但是否重要是一个不同的故事:

  • 微量标记是危险的,因为除非您实际执行多次操作,否则性能差异可以忽略不计
  • 有些LINQ查询会提前退出,因此编写一个等效的foreach并不像看起来那么简单。

简而言之,如果你运行一个分析器并看到一个真正的瓶颈,考虑切换(再次运行分析器以确保你修复它!)这确实是个案的基础。