当我试图迭代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++;
}
上层foreach(eddge中的IEdge)大约需要11000次迭代才能完成。 如果我删除行
,它会在几分之一秒内运行int co = row.Count();
来自代码。
row.Count()在所有循环中的最大值为10。
如果我取消注释
//foreach (string s in row)
//{
//}
完成代码执行大约需要10分钟。
IEnumerable类型是否有如此严重的性能问题.. ??
答案 0 :(得分:6)
这个答案是针对“我如何更快地加速”的隐含问题?抱歉,如果那不是实际上你所追求的,但......
您可以浏览行一次,按名称分组。 (我没有按照Marc的顺序进行排序 - 我只是在查询时查找两次:)
var lookup = dtRow.AsEnumerable()
.ToLookup(r => new { F1 = r.Field<string>("F1"),
F2 = r.Field<string>("F2") });
然后:
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)
{
...
}
}
答案 1 :(得分:1)
目前你有O(N * M)表现,如果N和M都很大,这可能是探测性的。我倾向于预先计算一些DataTable
信息。例如,我们可以尝试:
var lookup = dtRows.AsEnumerable().ToLookup(
row => string.Compare(row.Field<string>("F1"),row.Field<string>("F2"))<0
? Tuple.Create(row.Field<string>("F1"), row.Field<string>("F2"))
: Tuple.Create(row.Field<string>("F2"), row.Field<string>("F1")),
row => row.Field<string>("EdgeId"));
然后我们可以迭代:
foreach(IEdge ed in edCol)
{
var name1 = string.Compare(ed.Vertex1.Name,ed.Vertex2.Name) < 0
? ed.Vertex1.Name : ed.Vertex2.Name;
var name2 = string.Compare(ed.Vertex1.Name,ed.Vertex2.Name) < 0
? ed.Vertex2.Name : ed.Vertex1.Name;
var matches = lookup[Tuple.Create(name1,name2)];
// ...
}
(注意我为了方便而在那里强制使用升序字母对)