【发布时间】:2022-01-13 11:20:19
【问题描述】:
在下面的示例中,我期望 unordered_map 比 map 快,但事实并非如此。为什么会这样? unordered_map 是不是为了比常规地图更快而设计的?
#include <iostream>
#include <chrono>
#include <unordered_map>
#include <map>
int main()
{
std::unordered_map<int, double> grid_unmap_int;
std::map<int, double> grid_map_int;
size_t map_size = 1e7;
auto t1 = clock();
for (size_t i = 0; i < map_size; ++i) {
grid_unmap_int[i] = 1.0;
}
auto t2 = clock();
for (size_t k = 0; k < map_size; ++k) {
grid_map_int[k] = 1.0;
}
auto t3 = clock();
std::cout << "Insertion \n";
std::cout << "Filling unordered map int key: " << (t2 - t1) / static_cast<double>(CLOCKS_PER_SEC) << " seconds.\n";
std::cout << "Filling map int key: " << (t3 - t2) / static_cast<double>(CLOCKS_PER_SEC) << " seconds.\n";
std::cout << std::endl;
t1 = clock();
for (size_t i = 0; i < map_size; ++i) {
double b = grid_unmap_int[i] ;
}
t2 = clock();
for (size_t k = 0; k < map_size; ++k) {
double b = grid_map_int[k];
}
t3 = clock();
std::cout << "Retrieve \n";
std::cout << "Filling unordered map int key: " << (t2 - t1) / static_cast<double>(CLOCKS_PER_SEC) << " seconds.\n";
std::cout << "Filling map int key: " << (t3 - t2) / static_cast<double>(CLOCKS_PER_SEC) << " seconds.\n";
return 0;
}
编辑: 结果: enter image description here
【问题讨论】:
-
unordered_map并非设计为比常规地图更快。他们的工作方式不同。就像一个向量或列表。您不能称其中之一为 fastest 或 best。它们有强弱之分,使用哪一个取决于您的用例。 -
您在不提供统计信息或编译标志的情况下声称性能。
-
quick-bench 建议实际上 unordered_map 对于您的特定测试用例要快 5 倍:quick-bench.com/q/OK0XfUYBuko17quF1edWLIgLdK8
-
您的声明似乎与 cppreference 上的内容有冲突。 unordered_map - 元素的搜索、插入和删除具有平均恒定时间复杂度。 map - 搜索、删除和插入操作具有对数复杂度。跨度>
-
你用过
-O3吗?在我的系统上,unordered_map 的插入速度快了 2.8 倍,检索速度快了 10 倍。