搜索大量内存集合的性能问题
Performance issue with search of large in memory collection
我写了一个查询来从 transitiondata 中的 nodedata 中查找节点,但是由于它有 400 万条记录,它需要很长时间才能退出该循环。
我们有:
1. 过渡数据(集合)将具有 from 和 to 节点。
2.节点数据(集合)将具有等于 form 或 to 来自 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
,那么您将看不到太多性能优势,因此请确保尽可能多地重复使用它。
我写了一个查询来从 transitiondata 中的 nodedata 中查找节点,但是由于它有 400 万条记录,它需要很长时间才能退出该循环。
我们有:
1. 过渡数据(集合)将具有 from 和 to 节点。
2.节点数据(集合)将具有等于 form 或 to 来自 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
,那么您将看不到太多性能优势,因此请确保尽可能多地重复使用它。