【问题标题】:hash map fast inserts but slow retrieval哈希映射快速插入但检索缓慢
【发布时间】:2012-09-02 09:04:37
【问题描述】:

我正在使用 google 的 hash map 实现 谷歌::dense_hash_map。

Mine 是一个集群应用程序。所以我必须存储成对集群之间的距离。每个集群都有一个集群 id,它是一个 long int。所以密钥必须是 (long int id1, long int id2);

所以我决定在 hashMap 中需要一个 hashMap 才能工作。

这是我的距离存储哈希图的结构:

    google::dense_hash_map<long int, google::dense_hash_map<long int, double> > distanceHash;

这是在哈希映射中插入距离并检索它的代码

template<class Point>
void CoverTree<Point>:: insertDistance(long int id1, long int id2, long double distance)
{

  //Always id1 < id2;
  if(id1 < id2)
  {
    long temp = id1;
    id1 = id2;
    id2 = temp;
  }


  if(distanceHash.find(id1) == distanceHash.end())
  {
    google::dense_hash_map<long int, double> insideHash;
    insideHash.set_empty_key(-9999  );
    insideHash[id2] = distance;
    distanceHash[id1] = insideHash;
  }
  else
  {
    (distanceHash[id1])[id2] = (distanceHash[id1])[id2];
  }
}

template<class Point>
double CoverTree<Point>::getStoredDistance(long int id1, long int id2)
{
  if(id1 < id2)
  {
    long temp = id1;
    id1 = id2;
    id2 = temp;
  }

  google::dense_hash_map<long int, double>::iterator it;

  if(distanceHash.find(id1) != distanceHash.end())
  {

    if( distanceHash[id1].find(id2) != distanceHash[id1].end() ) 
      return distanceHash[id1][id2];
  }

  return -1;
}

我有数百万的距离。上次我检查过,大约有 600000000 个距离,其中 400000000 个是唯一的。这意味着重复 1/3 的距离,可以节省时间。

但是当我使用这个散列映射结构来存储距离时,程序运行得更慢了。这正是我发现的: 如果我只是使用距离函数存储距离,那么整个程序的运行速度会慢约 50 秒。 (200 秒带存储,150 秒不带)。 但是如果我存储距离,然后在计算距离之前使用哈希图检查距离是否存在,程序会变得慢得多(程序的 1/25 需要 300 秒)。

我不明白这种行为。我猜想一旦存储了距离,检索距离应该会更快。请让我知道这里出了什么问题以及是否可以更快。

P.S: RAM 不是问题。我在具有大约 160 GB RAM 的服务器上运行它。并且使用 hashmap 时的峰值内存消耗仅为总内存的 1.8%(使用 top 看到)。所以分页和抖动应该不是问题。

【问题讨论】:

  • getStoredDistance(long int id1, long int id2) 慢吗?
  • 你使用了 distanceHash.find(id1) N 次?它的复杂性是什么? NN ?然后你再放一个 N 就变成了 O(NN*N)
  • 是的 getStoredDistance 很慢。我知道怎么会是这样。我有一个想法可以解决这个问题。我将在每个点内都有一个哈希表。该哈希表存储从该特定节点到所有节点的距离。这将消除 istanceHash.find(id1) 因为我知道我需要距离的节点。
  • 你认为这行得通吗?我明天早上试试,然后在这里更新。
  • 你是对的。排序也可以解决这个问题。

标签: c++ performance hashmap


【解决方案1】:

But If I store the distances and then use the hashmap to check whether the distances exist before computing them, the program becomes way way slower(1/25th of the program takes 300 seconds).

我怀疑你找到了所有的元素来批准数据。

好的,hashmap查找时间复杂度是O(n),但是你使用的是

distanceHash.find(id1) 

getStoredDistance 函数中的两次 n 次,这使得最坏情况下的总复杂度为 O(n*n)

400M * 400M = 160000000000000000 太复杂了

【讨论】:

    猜你喜欢
    • 2020-01-17
    • 2011-10-01
    • 1970-01-01
    • 2017-10-04
    • 1970-01-01
    • 1970-01-01
    • 2019-11-24
    • 1970-01-01
    • 2012-12-16
    相关资源
    最近更新 更多