0

我如何多线程将所有元素添加到哈希表集合的这个简单操作?

foreach (var x in listx) //List of x
{
    String temp1 = x.sc;
    String temp2 = x.key;
    Nullable<int> temp3 = x.val;

    if ((null != temp2) && (string.Empty != temp2) && (int.MinValue != temp3) && "Fetch" == temp1)
    {
        if (false == htTempVal.ContainsKey(temp2.Trim()))
            htTempVal.Add(temp2.Trim(), temp3);
    }
}
4

3 回答 3

2

只有几个快速的性能改进:

(1) 在分配 temp2 时修剪 x.Key 而不是在循环中修剪 temp2。

(2) 是否可以将 htTempVal 设为 HashSet?HashSets 已经过优化,允许您只添加而不必担心检查密钥是否存在。通过为我的对象覆盖 GetHashCode 并使用 HashSet,我已经看到了惊人的性能改进。

这些都是小而容易的,但如果你有大约。100 万条记录,它可能会开始干扰性能。

于 2012-05-22T20:32:27.197 回答
0

找到一个线程安全的哈希表?

你能先对你的项目进行排序,然后只添加唯一的项目吗?可能有一个并行排序。然后您可以跳过 ContainsKey() 测试。

或者,为什么不跳过该测试,如果有错误则忽略该错误。

最后,一百万件物品怎么会很慢?一定有别的事情发生了。

于 2012-05-22T22:18:33.870 回答
0

您可以这样做,将哈希表替换为ConcurrentDictionary. 但是,不能保证您会获得任何加速,因为您基本上只是在循环中执行原子操作:

ConcurrentDictionary<String, Nullable<int>> htTempVal = 
           new ConcurrentDictionary<String, Nullable<int>>();

Parallel.ForEach (listx,
  x =>
  {
      String temp1 = x.sc;
      String temp2 = x.key.Trim();
      Nullable<int> temp3 = x.val;

      if ((null != temp2) && (string.Empty != temp2) && 
          (int.MinValue != temp3) && "Fetch" == temp1)
      {
          htTempVal.GetOrAdd(temp2, temp3);
      }
  });

ConcurrentDictionary.GetOrAdd原子地检查并添加一个键值对,如果它不存在,或者如果它已经在字典中,则返回该值(您可以忽略它)。

于 2012-05-22T22:28:07.430 回答