Linq选择新对象性能

时间:2014-05-18 20:26:01

标签: performance linq object select

我是Linq的新手,使用C#。当我执行以下操作时,我感到非常惊讶:

    var scores = objects.Select( i => new { object = i, 
        score1 = i.algorithm1(), 
        score2 = i.algorithm2(), 
        score3 = i.algorithm3() } );

    double avg2 = scores.Average( i => i.score2); // algorithm1() is called for every object
    double cutoff2 = avg2 + scores.Select( i => i.score2).StdDev(); // algorithm1() is called for every object

    double avg3 = scores.Average( i => i.score3); // algorithm1() is called for every object
    double cutoff3 = avg3 + scores.Select( i => i.score3).StdDev(); // algorithm1() is called for every object

    foreach( var s in scores.Where( i => i.score2 > cutoff2 | i.score3 > cutoff3 ).OrderBy( i => i.score1 )) // algorithm1() is called for every object
    {
        Debug.Log(String.Format ("{0} {1} {2} {3}\n", s.object, s.score1, s.score2/avg2, s.score3/avg3));
    }

我的新对象中的属性存储函数调用而不是值。每次我尝试访问属性时,都会调用原始函数。我认为这是浪费时间吗?我怎么能避免这个?

1 个答案:

答案 0 :(得分:1)

是的,您发现LINQ使用延迟执行。这是LINQ的正常部分,并且非常方便用于构建查询而不需要实际执行任何操作 - 这反过来对于可能巨大数据源的多个操作的管道非常有用流。

有关LINQ to Objects如何在内部工作的更多详细信息,您可能希望阅读我的Edulinq blog series - 它基本上是对整个LINQ to Objects的重新实现,一次一个方法。希望在结束时你能更清楚地了解会发生什么。

如果您想实现查询,只需调用ToListToArray即可构建结果的内存副本:

var scores = objects.Select( i => new { object = i, 
    score1 = i.algorithm1(), 
    score2 = i.algorithm2(), 
    score3 = i.algorithm3() } ).ToList();