搜索大量内存集合的性能问题

Performance issue with search of large in memory collection

我写了一个查询来从 transitiondata 中的 nodedata 中查找节点,但是由于它有 400 万条记录,它需要很长时间才能退出该循环。

我们有: 1. 过渡数据(集合)将具有 fromto 节点。
2.节点数据(集合)将具有等于 formto 来自 Transition data(Collection)

节点的键

这些集合中需要什么: 1. Collection 应该有Transition Data(from, to) 和相应的node from Node data(from key) and (to key)

我写的代码工作正常,但执行起来需要很多时间。下面是代码。

foreach (var trans in transitions)
        {
            string transFrom = trans.From;
            string transTo = trans.To;

            var fromNodeData = nodeEntitydata.Where(x => x.Key == transFrom).FirstOrDefault();
            var toNodeData = nodeEntitydata.Where(x => x.Key == transTo).FirstOrDefault();

            if (fromNodeData != null && toNodeData != null)
            {
                //string fromSwimlane = fromNodeData.Group;
                //string toSwimlane = toNodeData.Group;
                string dicKey = fromNodeData.sokey + toNodeData.sokey;
                if (!dicTrans.ContainsKey(dicKey))
                {
                    soTransition.Add(new TransitionDataJsonObject
                    {
                        From = fromNodeData.sokey,
                        To = toNodeData.sokey,
                        FromPort = fromPortIds[0],
                        ToPort = toPortIds[0],
                        Description = "SOTransition",
                        IsManual = true
                    });
                    dicTrans.Add(dicKey, soTransition);
                }
            }
        }

这是需要时间执行的循环。我知道问题在于那两个 Where 子句。因为转换将有 400k 而 nodeEntitydata 将有 400k。有人可以帮我解决这个问题吗?

使用直接访问字典条目:

var fromNodeData = nodeEntitydata[transFrom];
var toNodeData = nodeEntitydata[transTo];

看起来 nodeEntitydata 只是一个普通的 collection。您面临的问题是在内存 collection 上执行 Where 具有线性性能,并且您有很多记录要处理。

你需要的是 Dictionary。这对于搜索大型 collections 更有效,因为它使用 binary tree 进行搜索而不是线性搜索。

如果 nodeEntitydata 还不是 Dictionary,您可以像这样从中创建字典:

var nodeEntitydictionary = nodeEntitydata.ToDictionary(n => n.Key);

然后您可以像这样使用字典:

var fromNodeData = nodeEntitydictionary[transFrom];
var toNodeData = nodeEntitydictionary[transTo];

创建词典会相当慢,因此请确保只在填充 nodeEntitydata 时创建一次。如果您必须过于频繁地保留 re-instantiating 和 Dictionary,那么您将看不到太多性能优势,因此请确保尽可能多地重复使用它。