迭代IEnumerable <string>导致严重的性能问题

Raj*_*mar 0 c# performance

当我试图迭代IEnumerable类型时,我很少知道for循环的性能发生了什么.

以下是导致严重性能问题的代码

foreach (IEdge ed in edcol)
{
    IEnumerable<string> row = 
        from r in dtRow.AsEnumerable()
        where (((r.Field<string>("F1") == ed.Vertex1.Name) && 
                (r.Field<string>("F2") == ed.Vertex2.Name))
            || ((r.Field<string>("F1") == ed.Vertex2.Name) &&
                (r.Field<string>("F2") == ed.Vertex1.Name)))
        select r.Field<string>("EdgeId");
    int co = row.Count();
    //foreach (string s in row)
    //{

    //}
    x++;
}
Run Code Online (Sandbox Code Playgroud)

上层foreach(eddge中的IEdge)大约需要11000次迭代才能完成.如果我删除该行,它会在几分之一秒内运行

int co = row.Count();
Run Code Online (Sandbox Code Playgroud)

从代码.

row.Count()在所有循环中的最大值为10.

如果我取消注释

//foreach (string s in row)
//{

//}
Run Code Online (Sandbox Code Playgroud)

大约需要10分钟才能完成代码的执行.

IEnumerable类型是否有如此严重的性能问题.??

Jon*_*eet 6

这个答案是针对"如何让这个更快"的隐含问题?抱歉,如果那不是你真正想要的,但......

您可以遍历行一次,按名称分组.(我没有像Marc那样完成订购 - 我只是在查询时查找两次:)

var lookup = dtRow.AsEnumerable()
                  .ToLookup(r => new { F1 = r.Field<string>("F1"),
                                       F2 = r.Field<string>("F2") });
Run Code Online (Sandbox Code Playgroud)

然后:

foreach (IEdge ed in edcol)
{
    // Need to check both ways round...
    var first = new { F1 = ed.Vertex1.Name, F2 = ed.Vertex2.Name };
    var second = new { F1 = ed.Vertex2.Name, F2 = ed.Vertex1.Name };
    var firstResult = lookup[first];
    var secondResult = lookup[second];

    // Due to the way Lookup works, this is quick - much quicker than
    // calling query.Count()
    var count = firstResult.Count() + secondResult.Count();

    var query = firstResult.Concat(secondResult);

    foreach (var row in query)
    {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)