【问题标题】:std::map's behavior on referring to a keystd::map 在引用键时的行为
【发布时间】:2012-04-30 14:15:38
【问题描述】:

我正在编写一个数值模拟程序,使用 std::map 存储一些键值对。该地图用于存储模拟过程中演变的状态。键的类型是整数,对应于键的值表示相同键的副本数,即 std::map。对于模拟的每一步,我都需要计算同一个键有多少个值,所以我将通过以下代码进行检查

if (map[key]>0) {do something here with the number of copies}

但是,我很快发现这段代码不起作用,因为即使映射中没有这样的键,每当您调用 map[key] 时,它都会为该键生成一个占位符并将值设置为零;因此,我总是用 std::map.size() 多算键的总数。我稍后将代码更改如下以搜索密钥

if (map.find(key)!=map.end()) {...}

那么它是检查地图的键是否存在的唯一且最快的方法吗?我将运行模拟数亿次,它会经常调用上面的代码来检查密钥。改用 map.find() 会不会太慢?谢谢。

【问题讨论】:

    标签: c++ performance search map stdmap


    【解决方案1】:

    你可以使用 hash_map,它是你的键值类型最快的数据结构;

    你也可以使用map,但它比hash_map慢

    【讨论】:

      【解决方案2】:

      我认为检查密钥是否存在的各种方法在速度上没有太大差异。另一方面:如果你的键是整数并且范围是已知的,你可以只使用数组。

      顺便说一句: 我对简单数组、向量、地图和无序地图的速度很感兴趣。我编写了一个简单的程序,它执行 100000000 个容器 [n]++,其中 n 是 0 到 10000 范围内的随机数。结果:

      • 数组:1.27s
      • 矢量:1.36s
      • 无序地图:2.6s
      • 地图:11.6s 在这种简单情况下,循环 + 索引计算的开销约为 0.8 秒。

      所以这一切都取决于在其他地方花费了多少时间。如果它更多(每 100000000 次迭代),那么你使用什么并不重要。但如果不是,那可能会有很大的不同。

      【讨论】:

      • 感谢您花时间向我展示数据。我认为这给了我一些方向,我应该在我的情况下使用哪种结构。
      【解决方案3】:

      find 成员函数可能是查找键是否已在映射中的最快方法。也就是说,如果您不需要按顺序遍历地图中的项目,则使用std::unordered_map 可能会获得更好的性能。

      【讨论】:

      • ... 对于 int 键和值,还应考虑使用偶尔丢失(未使用)元素的简单数组。
      • 谢谢。是的,我也想过用数组代替。但在我的算法中,在某些情况下,我需要经常删除/插入键,因此总长度会有所不同。
      【解决方案4】:

      std::map 或哈希表 (std::unordered_map) 中,find 函数非常快,与使用 [] 下标运算符一样快。实际上,在没有找到元素的情况下更快,因为它不必插入一个。

      【讨论】:

      • 谢谢,似乎 unordered_map 是一种解决方案。所以 map 和 unordered_map 唯一的区别就是 key 不是动态排序的,对吧?
      • @user1285419:这是用法上的唯一区别。在下面,它们的存储方式非常不同(std::map 是平衡树,而std::unordered_map 是哈希表)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-06-23
      • 2014-08-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-04
      相关资源
      最近更新 更多