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

时间:2015-02-11 11:33:32

标签: c# performance foreach

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

我们拥有什么: 1.转换数据(收集),其中节点 2.节点数据(集合),其具有等于来自Transition数据(集合)的形式节点的键

这些系列需要什么: 1.应该具有Transition Data(from,to)和Node数据(来自key)和(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。有人可以帮我吗?

2 个答案:

答案 0 :(得分:1)

使用直接访问到词典条目:

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

答案 1 :(得分:0)

看起来nodeEntitydata只是一个普通的集合。您遇到的问题是,在内存集合中执行Where具有线性性能,并且您需要处理大量记录。

您需要的是Dictionary。这对于搜索大型集合来说效率更高,因为它使用binary tree进行搜索而不是线性搜索。

如果nodeEntitydata已经不是Dictionary,您可以像这样创建一个词典:

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

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

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

创建词典的速度相当慢,因此请确保只在填充nodeEntitydata时执行一次。如果您不得不经常重新实例化Dictionary,那么您将无法获得很多性能优势,因此请确保尽可能多地重复使用它。