如何在循环 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)。并且返回的枚举已经被缓冲,所以迭代几次不是问题。