【问题标题】:hash_map,map hash function for composite keyhash_map,map 复合键的散列函数
【发布时间】:2011-06-17 17:41:18
【问题描述】:

我有一个工作的 std::map 类,它有点慢,所以我想尝试其他数据结构

我的键是复合数据类型,例如

typedef struct {
  char * name;
  int offset;
}position;

对于 std::map,我使用以下偏序函数

struct cmp_position {
  bool operator()(const position& first,const  position& second) {
    int tmp = std::strcmp(first.name, second.name);
    if(tmp!=0)
      return tmp<0;
    else
      return first.offset<second.offset;
  }
};

我的地图定义是

typedef std::map<position,int,cmp_position> myMap;

我一直在查看 __gcc_ext::hash_map 这需要一个相等函数,它可能只是

struct positionEq
{
  bool operator()(const position& s1, const position & s2) const
  {
    return strcmp(s1.name, s2.name) == 0 && (s1.offset==s2.offset) ;
  }
};

这应该可行,但我的复合类型的哈希函数有问题。 我想我可以做类似的事情

position s;
char buf[100];
snprintf(buf,100,"%s:%d\n",s.name,s.offset);

但我无法将它们粘合在一起。

实际上 map 和 hash map 可能有点矫枉过正,因为我没有使用键的值,我只是使用我的 map 来检查是否存在。

我打算不使用 std::strings。

谢谢

编辑:

在上面的示例中,我尝试使用 std::set 而不是 std::map,并且 std::set 在填充和查找条目时始终较慢。尽管总体比较如下表所示,但它使用的内存要少得多。我试着跑了 10 次

         Set        map
 size   1.8gig     3.1gig
 pop    <15sec     <14sec
 find   <12sec     <9sec 

我使用了一个包含超过 34 个 mio 条目的数据集,在填充数据结构后,我尝试查找所有 34 个 mio 元素。我想结论是,除了节省内存之外,std::set 更差。

【问题讨论】:

  • 请定义“有点慢”。什么是慢?插入?寻找?遍历?
  • 学习 unordered_map 比学习 hash_map 好。两者都是哈希表,但 unordered_map 是(或很快将是)标准。
  • 如果不需要值,请使用set/hash_set/unordered_set
  • 在发布版本中应该有点快,您如何分析以确定这一点?与 Steve 一致,如果您不需要值,请使用更合适的容器。

标签: c++ stl cstring


【解决方案1】:

您是否尝试过使用存储散列值name 的键结构(例如使用boost::hash_value) - 这样比较关键对象将只是两个数字比较,这应该很快。

尝试使用unordered_set 对其进行测试。 boost::multi_index_container 声称优于 std::set,在某些情况下,您可以看看这是否会加快速度(有关其使用示例,请参阅我的回答 here)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-03
    • 1970-01-01
    • 2010-10-14
    • 1970-01-01
    • 1970-01-01
    • 2016-05-02
    相关资源
    最近更新 更多