如何提高 foreach 循环的
foreach (var item in pList)
{
var foundedItem = source.FirstOrDefault(x => x.LongRecordId == item.LongRecordId);
if (foundedItem != null && !selectionList.Contains(foundedItem))
{
foundedItem.Readonly = pReadonly;
selectionList.Add(foundedItem);
}
}
答案 0 :(得分:4)
如果source
以及pList
很长,您可以尝试将source
转换为Dictionary
:
// Provinding that all LongRecordId are distinct
var dict = source
.ToDictionary(item => item.LongRecordId, item => item);
...
foreach (var item in pList) {
MyRecord foundItem = null; //TODO: Put the right type here
// Instead of O(N) - FirstOrDefault we have O(1) TryGetValue
if (dict.TryGetValue(item.LongRecordId, out foundItem)) {
foundItem.Readonly = pReadonly;
selectionList.Add(foundItem);
}
}
修改:如果您想确保selectionList
仅包含不同的项目(请参阅Ferhat Sayan的评论),请尝试HashSet
...
HashSet<MyRecord> selectedHash = new HashSet<MyRecord>(selectionList);
foreach (var item in pList) {
MyRecord foundItem null; //TODO: Put the right type here
// Instead of O(N) - FirstOrDefault we have O(1) TryGetValue
if (dict.TryGetValue(item.LongRecordId, out foundItem)) {
foundItem.Readonly = pReadonly;
selectedHash.Add(foundItem);
}
}
selectionList = selectedHash.ToList();
答案 1 :(得分:2)
我建议对这段代码进行分析。
我想最耗时的电话是FirstOrDefault-Extension方法。
如果有任何性能提升,使用而不是foreach不太可能给你很多。
很可能你的问题源于你的上下文变量,可能是一个非常大的源列表?
总的来说,此代码部分可能不是寻找性能改进的最佳位置。如果这是唯一的地方,你应该考虑重新设计。
如果您有非常大的列表并且不担心并发问题,那么您可以使用并行或多处理路由。 parallel.foreach是进行某些测试的便宜方式。
使用Dictionary而不是List应该可以加快速度。如果您使用HashSet(以产生uniqunes的好处),请注意实现正确的IEqualityComparer,或者当您添加依赖于DefaultComparer的大量项目时甚至可以lose performance。