【问题标题】:Fast way to build a hash set, single or multiple thread?构建散列集的快速方法,单线程还是多线程?
【发布时间】:2014-03-19 17:44:13
【问题描述】:

我想知道为什么构建哈希集更快。

我的过程是这样的:

1、DB访问(单线程),得到一个的ID列表。

2,
A计划

foreach( var oneID in IDs)
{
    myHashSet.add(oneID);
}

B计划

Parallel.ForEach(IDs,myPallOpt,(oneID)=>
{
    myHashSet.add(oneID);
});

那么,A 计划和 B 计划哪个更快?

谢谢

【问题讨论】:

  • 哈希集不是线程安全的。
  • 我相当肯定 CPU 可以跟上来自数据库的 I/O。只要确保流式传输“大”I/O 步骤即可。无论如何,投票结束,因为问题是“最快的”,尽管没有确定问题/环境。使用 97/3 规则。
  • 我正要和@SLaks 说同样的话...虽然 OP 可以使用 ConcurrentDictionary...除非 OP 可以接受某些实际上没有添加到 hashSet 中的项目(或以其他方式打破)。
  • @Xantix:那可能会更慢。
  • 您的数据库服务是否会比通过一个连接的完整请求更快地通过多个连接获取部分请求?根据提供的信息,我们无法回答。这是问题的症结所在,哈希集的性能不太相关。 (尽管并行添加到非线程安全的集合中注定会失败。)

标签: c# multithreading hash hashset


【解决方案1】:

HashSet<T> 不是线程安全的,所以第二个选项(使用Parallel.ForEach)可能会导致错误。绝对应该避免。

最好的选择可能是直接从结果中构建哈希集:

var myHashSet = new HashSet<int>(IDs);

请注意,这仅在 HashSet 仅用于包含此集合中的项目时才有效。如果您要添加到现有的 HashSet&lt;T&gt;foreach(您的第一个选项)可能是最佳选择。

【讨论】:

    【解决方案2】:

    Plan B 可能行不通,因为它可能不是线程安全的(大多数 .NET 集合类都不是线程安全的)。您可以通过使其访问线程安全来修复它,但这本质上意味着对它的序列化访问,这并不比单线程更好。唯一有意义的情况是,在您的 for 循环开始和实际添加之间,您有一些 CPU 密集型处理可以很好地并行化。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-08-16
      • 2021-12-06
      • 2021-02-20
      • 2014-08-08
      • 2011-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多