ConcurrentDictionary.对于基于int数组(Key字段)的筛选,速度非常慢
本文关键字:筛选 速度 非常 字段 于基于 int 数组 Key ConcurrentDictionary | 更新日期: 2023-09-27 18:21:30
我有以下
var links = new ConcurrentDictionary<int, Link>();
它填充了大约20k条记录,我有另一个字符串数组(List),我使用以下方法将其转换为int数组。
var intPossible = NonExistingListingIDs.Select(int.Parse); //this is very fast but need to be done
这是相当快的。但我想创建一个新的列表,或者只筛选出与ConcurrentDictionary的Key元素匹配的intPossible数组中实际存在的"链接"。
我使用了where子句,但实际过滤需要大约50秒,这对我想做的事情来说非常慢
var filtered = links.Where(x => intPossible.Any(y => y == x.Key)).ToList();
我知道intersect很快,但我有一个int数组,而intersect不能针对ConcurrentDictionary 使用它
我如何过滤链接,使其更快一点,而不是50秒。
您需要用更快速的东西来替换O(n)内部查找,比如为查找提供O(1)复杂性的哈希集。
所以
var intPossible = new HashSet<int>(NonExistingListingIDs.Select(int.Parse));
和
var filtered = links.Where(x => intPossible.Contains(x.Key)).ToList();
这将避免对links
中的每个项目迭代大部分intPossible
。
或者,林克是你的朋友:
var intPossible = NonExistingListingIDs.Select(int.Parse);
var filtered =
links.Join(intPossible, link => link.Key, intP => intP, (link, intP) => link);
Join的实现与我上面所做的基本相同。
另一种方法是枚举列表并使用字典的索引器。。。可能会干净一点。。。
var intPossible = NonExistingListingIDs.Select(int.Parse);
var filtered = from id in intPossible
where links.ContainsKey(id)
select links[id];
你可能也想在里面放一个.ToList()
。。。
这实际上应该比@spender的解决方案稍微快一点,因为.Join
必须创建一个新的HashTable,而此方法使用ConcurrentDictionary中的HashTable。