【问题标题】:ConcurrentDictionary.Where very slow for filtering based int array (Key field)ConcurrentDictionary.Where 基于 int 数组的过滤非常慢(关键字段)
【发布时间】:2014-11-04 19:27:30
【问题描述】:

我有以下

  var links = new ConcurrentDictionary<int, Link>();

其中填充了大约 20k 条记录,我有另一个字符串数组(列表),我使用以下方法将其转换为 int 数组。

var intPossible = NonExistingListingIDs.Select(int.Parse); //this is very fast but need to be done

这是相当快的。但我想创建一个新列表或仅过滤掉与 intPossible 数组中与 ConcurrentDictionary 的 Key 元素匹配的实际内容的“链接”。

我使用 where 子句进行以下操作,但实际过滤需要大约 50 秒,这对于我想要做的事情来说非常慢。

var filtered = links.Where(x => intPossible.Any(y => y == x.Key)).ToList();

我知道 intersect 非常快,但我有一个整数数组,并且 intersect 不能针对 ConcurrentDictionary 使用它

我怎样才能过滤链接更快而不是 50 秒。

【问题讨论】:

    标签: c# performance linq


    【解决方案1】:

    您需要将 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

    或者,Linq 是你的朋友:

    var intPossible = NonExistingListingIDs.Select(int.Parse);
    var filtered =
      links.Join(intPossible, link => link.Key, intP => intP, (link, intP) => link);
    

    Join 的实现和我上面做的差不多。

    【讨论】:

    • 第一个版本运行良好,现在以毫秒为单位。谢谢,等待将其标记为答案。
    • @Zoinky,是的......我期待如此。您的intPossible 实际上不是一个数组,而是一个未实现的 IEnumerable,这可能使问题更加复杂。每次调用.Any 对其进行迭代时,它都必须重新解析NonExistingListingIDs 中的字符串,这会给操作增加相当大的负担。通过将其放入 HashSet 中,它只会被枚举一次(但自然需要更多内存来存储)。
    【解决方案2】:

    另一种方法是枚举您的列表并使用字典的索引器...可能更简洁...

    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。

    【讨论】:

      猜你喜欢
      • 2013-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-11
      • 1970-01-01
      • 1970-01-01
      • 2013-01-19
      • 1970-01-01
      相关资源
      最近更新 更多