代码之家  ›  专栏  ›  技术社区  ›  Jeroen

Linq ForEach性能

  •  7
  • Jeroen  · 技术社区  · 15 年前

    我正在用大约1000个元素迭代一个匿名类型。

    这里的问题是,当循环内部发生的事情不到1毫秒时,我的循环如何可能需要大约3秒钟才能完成。对于1000个元素,我认为循环必须在第二个元素内完成,而不是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
                        }
    
    4 回复  |  直到 15 年前
        1
  •  14
  •   Billy ONeal IS4    15 年前

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

        2
  •  15
  •   Jon Skeet    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-to-objects、linq-to-sql还是其他什么?什么类型的 tt ?

        3
  •  7
  •   µBio    15 年前

    这是延期执行。 写 x.ToList(); 也需要3秒钟。

        4
  •  1
  •   StuartLC    15 年前

    在实现IEnumerable(x)之前,不会对其进行评估