我认为这个问题部分得到了回答,因为没有提供有关使用“int”类型作为键的性能信息。我进行了自己的分析,并发现当使用整数作为键时,在许多实际情况下,std::map可以比std::unordered_map更快地执行(速度更快)。
整数测试
测试场景包括使用连续和随机键以及字符串值填充映射,字符串长度在[17:119]范围内且为17的倍数。测试是在元素数量[10:100000000]的幂级别下进行的。
Labels:
Map64: std::map<uint64_t,std::string>
Map32: std::map<uint32_t,std::string>
uMap64: std::unordered_map<uint64_t,std::string>
uMap32: std::unordered_map<uint32_t,std::string>
插入
Labels:
Sequencial Key Insert: maps were constructed with keys in the range [0-ElementCount]
Random Key Insert: maps were constructed with random keys in the full range of the type
插入操作的结论:
- 在std::map中插入分散的键(spread keys),当地图大小小于10000个元素时,性能优于std::unordered_map。
- 在std::map中插入密集的键(dense keys),当地图大小小于1000个元素时,与std::unordered_map没有性能差异。
- 在所有其他情况下,std::unordered_map倾向于表现更快。
查找
Labels:
Sequential Key - Seq. Search: Search is performed in the dense map (keys are sequential). All searched keys exists in the map.
Random Key - Rand. Search: Search is performed in the sparse map (keys are random). All searched keys exists in the map.
(label names can be miss leading, sorry about that)
关于“查找”的结论:
- 当映射大小在100万个元素以下时,搜索 std::map 的性能略优于 std::unordered_map。
- 在密集的 std::map 上搜索优于 std::unordered_map。
查找失败
Labels:
Sequential Key - Rand. Search: Search is performed in the dense map. Most keys do not exists in the map.
Random Key - Seq. Search: Search is performed in the sparse map. Most keys do not exists in the map.
(label names can be miss leading, sorry about that)
失败查询结论:
总体结论
即使需要速度,对于整数键,std::map
在许多情况下仍然是更好的选择。作为一个实际例子,我有一个字典,查询从不失败,尽管键具有稀疏分布,在元素计数低于 1K 的情况下,它的性能将不会比 std::unordered_map
差,并且内存占用显著更低。
字符串测试
为了参考,这里介绍 字符串[string] 映射的时间。键字符串由随机 uint64_t 值形成,值字符串与其他测试中使用的相同。
Labels:
MapString: std::map<std::string,std::string>
uMapString: std::unordered_map<std::string,std::string>
评估平台
操作系统:Linux - OpenSuse Tumbleweed
编译器:g++(SUSE Linux)11.2.1 20210816
CPU:Intel(R)Core(TM)i9-9900 CPU @ 3.10GHz
RAM:64Gb