2010-08-09 69 views
7

我正在遍历一个具有大约1000个元素的匿名类型。linq foreach性能

这里的问题是,我的循环如何才能完成需要将近3秒的时间,而循环内部发生的时间少于1毫秒。有一千个元素,我认为循环必须在第二秒钟内完成,而不是3.

有没有办法让迭代更快?

// takes 1ms to complete 
     var x = tt.Where(p => p.Methods.Count() > 0 && p.PerWeek != this.Project.WorkDaysCount && !p.IsManual); 

// takes almost 3 seconds to complete 
        foreach (var item in x) 
        { 
         // do stuff that takes < 1 ms 
        } 

回答

14

Linq使用延迟执行。您的linq查询实际上不会执行,直到有人使用返回的IEnumerable。你看到的执行时间是查询的结果,而不是foreach。

+0

Ofcourse。我没有意识到。谢谢。 – Jeroen 2010-08-09 16:13:32

7

延期执行。 写x.ToList();它也需要~3秒。

15

两个直接的建议:

  • 不要使用p.Methods.Count() > 0 - 需要执行完整计数,即使你只需要知道,如果有任何元素。改为使用p.Methods.Any()
  • 不要在每次迭代时计算this.Project.WorkDaysCount。我们不知道那里发生了什么,但它可能很昂贵。预先计算并使用常量。

下面是改进查询代码:

int workDaysCount = Project.WorkDaysCount; 
var x = tt.Where(p => p.Methods.Any() && 
       p.PerWeek != workDaysCount && 
       !p.IsManual); 

正如其他人所说,原因查询建筑本身不带任何显著时间,这就是它没有做任何实际工作。但是,知道这并不会让它更快,当然:)

除此之外,我们将需要更多地了解上下文。这是LINQ到对象,LINQ到SQL,还是其他? tt的类型是什么?

+0

这是相当复杂的模块的一部分。 tt是一个小组的结果,并建立一个子集合。方法基于一些标准。这是对象的逻辑。根据您的信息,我认为我可以进一步优化。谢谢! – Jeroen 2010-08-09 16:20:23

1

您的IEnumerable(x)将不会被评估,直到您实现它