为什么我的std::unordereded_map访问时间不是恒定的
Why is my std::unordered_map access time not constant
我写了一些代码来测试我的无序映射性能,并将2分量向量作为关键字。
std::unordered_map<Vector2i, int> m;
for(int i = 0; i < 1000; ++i)
for(int j = 0; j < 1000; ++j)
m[Vector2i(i,j)] = i*j+27*j;
clock.restart();
auto found = m.find(Vector2i(0,5));
std::cout << clock.getElapsedTime().asMicroseconds() << std::endl;
以上代码的输出:56(微秒)当我将for循环中的1000替换为100时,输出为2(微秒)时间不是应该是恒定的吗?
我的Vector2i:的哈希函数
namespace std
{
template<>
struct hash<Vector2i>
{
std::size_t operator()(const Vector2i& k) const
{
using std::size_t;
using std::hash;
using std::string;
return (hash<int>()(k.x)) ^ (hash<int>()(k.y) << 1);
}
};
}
编辑:我添加了这个代码来计算for循环后的冲突:
for (size_t bucket = 0; bucket != m.bucket_count(); ++bucket)
if (m.bucket_size(bucket) > 1)
++collisions;
具有100*100个元素:碰撞=256
1000*1000个元素:冲突=2048
哈希表保证恒定的摊销时间。如果哈希表平衡良好(即哈希函数良好),那么大多数元素将均匀分布。然而,如果哈希函数不太好,可能会发生很多冲突,在这种情况下,要访问元素,通常需要遍历链表(在其中存储冲突的元素)。因此,首先要确保负载因子和哈希函数在您的情况下是可以的。最后,确保您在发布模式下编译代码,并启用优化(例如,针对g++/crang++的-O3
)。
这个问题可能也很有用:如何创建一个具有64位输出的好的hash_combine(灵感来自boost::hash_combie)。
相关文章:
- C++为构建时间获取QDateTime的可靠方法
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- 从持续时间构造std::chrono::system_clock::time_point
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- 使用一个考虑到std::map中键值的滚动或换行的键
- 向量 <int> a {N, 0} 和 int arr a[N] = {0} 的时间复杂度有什么区别
- while循环中while循环的时间复杂度是多少
- 使用简单类型列表实现的指数编译时间.为什么
- 是否可以在编译时初始化数组,以便在运行时不会花费时间?
- 在已经使用Git的情况下减少编译时间
- 有没有一种方法可以创建一个带有哈希表的数据库,该哈希表具有恒定时间查找功能
- 如何将包含epoch时间的十六进制字符串转换为time_t
- 从文本文件中读取时钟时间和事件时间并进行处理
- 具有未知值时的时间复杂性
- std::map的时间复杂度是多少
- 一个清晰的函数的时间复杂度是多少,根据大 O,是 std::map
- std::map中find()的时间复杂性
- 下面使用Map和Vector实现递归级阶遍历的时间复杂度是多少
- c++ STL map:是访问时间0(1)
- std::map 获取最低的 n 个元素时间