2015-02-11 41 views
1

我编写了一个查询来从transitiondata中查找nodedata中的节点,但由于它有400万条记录,因此需要相当长的时间才能从该循环中出来。搜索大内存集合时的性能问题

我们有什么: 1.转换数据(集),这将有节点。
2.节点数据(集合),这将有键,其是等于形式或从过渡数据(集合)节点

需要这些集合的什么: 1.收集应当具有过渡数据(从,到)和从节点数据(从密钥)和(到密钥)的相应节点

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

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。有人可以帮助我吗?

+0

注意:“拉赫”是印度数字系统中的一个单位。它在十进制数字系统中等于'100 000'。 40拉赫是'400 000'。 – 2015-02-11 11:37:25

+1

'nodeEntityData'是什么样的集合? – DrKoch 2015-02-11 11:42:33

回答

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,那么你不会看到很多性能优势,所以请确保尽可能地重用它。

1

使用直达到字典条目:

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