如何在循环 C# 中插入列表时提高性能
How can I improve the performance while inserting to a list in while looping C#
我怎样才能提高下面代码块的性能。 distinctUniqueIDs 列表有超过 10000 条记录。我已经尝试过并行执行,但它并没有产生太大的区别。有没有其他的space可以优化
for (int i = 0; i < distinctUniqueIDs.Count; i++)
{
long distinctUniqueID = distinctUniqueIDs[i];
try
{
if (!SmartAppConfigMapDict.ContainsKey(distinctUniqueID))
{
appconfigTemp = new SmartAppconfigRootElementMap();
filteredList = validAppConfig.Where(m => m.UniqueID == distinctUniqueID);
if (filteredList?.Count() > 0)
{
appconfigTemp.AppConfig = filteredList.First();
appconfigTemp.RootElements = filteredList.ToDictionary(m =>
m.RootElementVersionID, m => m.RootElementName);
appconfigTemp.RootElementPrimaryKeyMaps = filteredList.ToDictionary(m =>
m.RootElementVersionID, m => new RootElementPrimaryKeyMap
{
RootElementName = m.RootElementName,
RootElementVersionID = m.RootElementVersionID,
ChildElementDesc = m.ChildElementDesc,
ChildElementName = m.ChildElementName,
ChildElementPath = m.ChildElementPath,
ActualRootElementVersionID = m.ActualRootElementVersionID,
ActualRootElementName = m.ActualRootElementName
});
SmartAppConfigMapDict.Add(distinctUniqueID, appconfigTemp);
if (queryRootElementMap.ContainsKey(appconfigTemp.AppConfig.QueryID))
{
queryRootElementMap[appconfigTemp.AppConfig.QueryID]
.Add(appconfigTemp);
}
else
{
appConfigRootMapSubList = new List<SmartAppconfigRootElementMap>();
appConfigRootMapSubList.Add(appconfigTemp);
queryRootElementMap.Add(appconfigTemp.AppConfig.QueryID,
appConfigRootMapSubList);
}
}
}
}
catch (Exception)
{
continue;
}
}
罪魁祸首应该是
filteredList = validAppConfig.Where(m => m.UniqueID == distinctUniqueID);
首先,LINQ Where
是线性时间复杂度 O(N) 的低效方法。不建议在循环内使用此类方法。
其次,由于 LINQ 延迟执行,上述线性搜索被执行了几次 - 基本上由应用于 filteredList
- filteredList?.Count()
、filteredList.First()
和 2 [=18 的每个运算符执行=]来电。
你可以做的是在循环外提前准备一个基于哈希的快速查找数据结构(例如,Lookup)并在循环内使用它。
例如在循环外添加类似这样的内容:
var validAppConfigsByUniqueID = validAppConfig.ToLookup(m => m.UniqueID);
并在里面替换
filteredList = validAppConfig.Where(m => m.UniqueID == distinctUniqueID);
if (filteredList?.Count() > 0)
和
var filteredList = validAppConfigsByUniqueID[distinctUniqueID];
if (filteredList.Any())
请注意,validAppConfigsByUniqueID[distinctUniqueID]
操作具有常数时间复杂度 O(1)。并且返回的枚举已经被缓冲,所以迭代几次不是问题。
我怎样才能提高下面代码块的性能。 distinctUniqueIDs 列表有超过 10000 条记录。我已经尝试过并行执行,但它并没有产生太大的区别。有没有其他的space可以优化
for (int i = 0; i < distinctUniqueIDs.Count; i++)
{
long distinctUniqueID = distinctUniqueIDs[i];
try
{
if (!SmartAppConfigMapDict.ContainsKey(distinctUniqueID))
{
appconfigTemp = new SmartAppconfigRootElementMap();
filteredList = validAppConfig.Where(m => m.UniqueID == distinctUniqueID);
if (filteredList?.Count() > 0)
{
appconfigTemp.AppConfig = filteredList.First();
appconfigTemp.RootElements = filteredList.ToDictionary(m =>
m.RootElementVersionID, m => m.RootElementName);
appconfigTemp.RootElementPrimaryKeyMaps = filteredList.ToDictionary(m =>
m.RootElementVersionID, m => new RootElementPrimaryKeyMap
{
RootElementName = m.RootElementName,
RootElementVersionID = m.RootElementVersionID,
ChildElementDesc = m.ChildElementDesc,
ChildElementName = m.ChildElementName,
ChildElementPath = m.ChildElementPath,
ActualRootElementVersionID = m.ActualRootElementVersionID,
ActualRootElementName = m.ActualRootElementName
});
SmartAppConfigMapDict.Add(distinctUniqueID, appconfigTemp);
if (queryRootElementMap.ContainsKey(appconfigTemp.AppConfig.QueryID))
{
queryRootElementMap[appconfigTemp.AppConfig.QueryID]
.Add(appconfigTemp);
}
else
{
appConfigRootMapSubList = new List<SmartAppconfigRootElementMap>();
appConfigRootMapSubList.Add(appconfigTemp);
queryRootElementMap.Add(appconfigTemp.AppConfig.QueryID,
appConfigRootMapSubList);
}
}
}
}
catch (Exception)
{
continue;
}
}
罪魁祸首应该是
filteredList = validAppConfig.Where(m => m.UniqueID == distinctUniqueID);
首先,LINQ Where
是线性时间复杂度 O(N) 的低效方法。不建议在循环内使用此类方法。
其次,由于 LINQ 延迟执行,上述线性搜索被执行了几次 - 基本上由应用于 filteredList
- filteredList?.Count()
、filteredList.First()
和 2 [=18 的每个运算符执行=]来电。
你可以做的是在循环外提前准备一个基于哈希的快速查找数据结构(例如,Lookup)并在循环内使用它。
例如在循环外添加类似这样的内容:
var validAppConfigsByUniqueID = validAppConfig.ToLookup(m => m.UniqueID);
并在里面替换
filteredList = validAppConfig.Where(m => m.UniqueID == distinctUniqueID);
if (filteredList?.Count() > 0)
和
var filteredList = validAppConfigsByUniqueID[distinctUniqueID];
if (filteredList.Any())
请注意,validAppConfigsByUniqueID[distinctUniqueID]
操作具有常数时间复杂度 O(1)。并且返回的枚举已经被缓冲,所以迭代几次不是问题。