我的自定义使用 std::unordered_map 的性能非常慢
Very slow performance of my custom use of std::unordered_map
我正在尝试在unordered_map中存储图形的一些信息。每条边都有一些参数。有 120 条边,每条边有 90*2 个不同的参数。
我有以下std::unordered_map<>
实现
typedef std::tuple<int, int, int, int> metric_tuple_key; // metric tuple key
// define a hash function for this metric_tuple_key tuple
struct m_KeyHash : public std::unary_function<metric_tuple_key, std::size_t> {
std::size_t operator()(const metric_tuple_key& k) const {
// the magic operation below makes collisions less likely than just the standard XOR
std::size_t seed = std::hash<int>()(std::get<0>(k));
seed ^= std::hash<int>()(std::get<1>(k)) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
seed ^= std::hash<int>()(std::get<2>(k)) + 0x9e3779b97f4a7c15 + (seed << 6) + (seed >> 2);
return seed ^ (std::hash<char>()(std::get<3>(k)) + 0x9e3779b9 + (seed << 6) + (seed >> 2));
}
};
// define the comparison operator for this metric_tuple_key tuple
struct m_KeyEqual : public std::binary_function<metric_tuple_key, metric_tuple_key, bool> {
bool operator()(const metric_tuple_key& v0, const metric_tuple_key& v1) const {
return (std::get<0>(v0) == std::get<0>(v1) && std::get<1>(v0) == std::get<1>(v1) &&
std::get<2>(v0) == std::get<2>(v1) && std::get<3>(v0) == std::get<3>(v1));
}
};
std::unordered_map<metric_tuple_key, double, m_KeyHash, m_KeyEqual> _metrics;
我能够通过创建元组键将这些值插入_metrics
。
现在,我想在指定键时从_metrics
中获取一些值。
//Retrieve around 120 double values. Total number of entries in _metrics is 21600
double k = _metrics.at((std::make_tuple(m, k, edge.first, edge.second))). //do this 120 times
事实证明,这非常慢(几乎 400 毫秒(。我希望它大约需要一毫秒或更短的时间。
我做错了什么还是 std::unordered_map 不适合我的用例。我以前使用过python字典来解决同样的问题,并且在python字典中检索值几乎是即时的
编辑: 一些unordered_map统计数据:
max_load_factor: 1
size: 21600
bucket_count: 25717
load_factor: 0.839911
编辑:计时器代码:
#include <chrono>
#include <iostream>
#include <iomanip>
class Timer {
private:
std::chrono::time_point<std::chrono::steady_clock> start , stop;;
public:
void startClock();
void stopClock();
void elapsedTime(std::string &message);
};
#include "Timer.hpp"
void Timer::startClock() {
start = std::chrono::steady_clock::now();
}
void Timer::stopClock() {
stop = std::chrono::steady_clock::now();
}
void Timer::elapsedTime(std::string &message) {
auto diff = stop - start;
std::cout << "Elapsed time for " <<message<< " " << std::setprecision(13) <<std::chrono::duration <double, std::milli> (diff).count() << " ms" << std::endl;
}
并且时间测量是
T_met.startClock();
for (const auto& edges: list_of_arcs())
{
double k = _metrics.at((std::make_tuple(m, k, edge.first, edge.second)))
}
T_met.stopClock();
搜索持续时间取决于哈希值的质量。 对于测试,您可以使用"map" - 它具有稳定的搜索持续时间。 如果 map 比无序列映射快 - 你的哈希值很糟糕。
相关文章:
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- OpenMP阵列性能较差
- 使用一个考虑到std::map中键值的滚动或换行的键
- 递归列出所有目录中的C++与Python与Ruby的性能
- std::map 索引运算符与插入方法的性能
- 使用STD :: MAP在数据及其性能问题中查找重复项.我可以预先分配吗?
- ID3D11DEVICECONTEXT :: MAP慢速性能
- 我会看到使用 std::map 而不是 vector<pair<string、string> > 的性能提升吗?
- C++ map<std::string> vs map<char *> 性能(我知道,"again?" )
- map< "string" ,..> 和 map<int,..> 之间的性能差异?
- A* 路径查找中 std::map 性能的视觉C++性能问题
- 哪个性能更快?具有 N 个派生类型的 vtable 查找,或具有 N 个元素的 std::map 查找
- 堆与读取Map最左边节点的相对性能
- c++中List和Map之间的性能问题
- map(和族)查找性能问题
- 为什么unordered_map和map给出相同的性能?
- c++中简单迭代list over map的性能比较
- std::map::find性能取决于键大小吗?