焦小花同学

parallel-hashmap:并发哈希表的极致,比标准库快3倍

Image

等你来关注!

parallel-hashmap:并发哈希表的极致,比标准库快3倍

用 C++ 开发高性能并发程序,最让人头疼的就是数据结构的效率问题,尤其是哈希表。在多线程环境下,std::unordered_map 不仅慢,还需要额外的锁来保证线程安全,简直让人抓狂。今天咱们聊点硬核的——parallel-hashmap,一个比标准库快 3 倍的并发哈希表库。

哈希表的并发问题:锁?不锁?

Image

普通的哈希表,比如 std::unordered_map,在多线程环境下操作时,得加锁,不然数据就乱套了。锁呢,简单粗暴,但代价也大,会让性能掉到谷底。而 parallel-hashmap 的牛逼之处就在于它的设计几乎把锁的开销降到了最低,甚至在有些场景下完全不用锁。

看看下面的代码,感受下这库的基本用法:

#include “parallel_hashmap/phmap.h”

#include <iostream>

#include <thread>

#include <vector>

int main() {

// 声明一个并发哈希表

phmap::parallel_flat_hash_map<int, std::string> map;

// 多线程插入数据

std::vector<std::thread> threads;

for (int i = 0; i < 4; ++i) {

threads.emplace_back([&map, i]() {

for (int j = 0; j < 1000; ++j) {

map[i * 1000 + j] = “value_” + std::to_string(i * 1000 + j);

}

});

}

// 等待线程完成

for (auto &t : threads) {

t.join();

}

// 打印结果

std::cout << “Map size: ” << map.size() << std::endl;

return 0;

}

运行后会发现,这玩意儿不仅快,而且线程安全,数据一点儿不乱。多线程插入 4000 条数据,map.size() 会准确输出 4000。

温馨提示:parallel-hashmap 提供了多种哈希表类型,比如 parallel_flat_hash_map 和 parallel_node_hash_map。选择的时候要根据你的场景来定,前者适合性能优先的场景,后者则在动态内存管理方面表现更好。

为什么它这么快?

Image

这库快的秘诀有两个:分区锁和缓存友好的实现。简单说,它把哈希表拆成了多个“区域”,每个区域有自己的锁,操作不同区域的数据时,线程之间互不干扰。再配合缓存友好的数据布局,极大地减少了 CPU 缓存失效的概率。

下面这个示例演示了“分区锁”的威力:

#include “parallel_hashmap/phmap.h”

#include <iostream>

#include <thread>

#include <vector>

int main() {

phmap::parallel_flat_hash_map<int, int, std::hash<int>, std::equal_to<int>,

std::allocator<std::pair<const int, int>>, 8> map;

// 默认分成 8 个锁区

map[1] = 10;

map[2] = 20;

// 查看分区数量

std::cout << “Number of submaps (locks): ” << map.subcnt() << std::endl;

return 0;

}

在这里,8 是锁区的数量,你可以根据实际应用的线程数量调整它。锁区多了,线程竞争就少了,但太多了也会浪费内存,得权衡。

小踩坑提醒: 如果你用的是动态哈希表(比如 parallel_node_hash_map),插入数据时可能会触发内部的动态扩容,虽然库已经优化了这部分逻辑,但扩容时仍然会有些性能抖动。

应用场景

Image

parallel-hashmap 适合用在多线程、高并发的场景,比如:

  • Web 服务的缓存系统 :快速存取请求数据,减少锁竞争。

  • 游戏开发 :大规模玩家数据的并发读写。

  • 日志和监控系统 :高频日志 key 的统计和聚合。

这一切的前提是你得用对地方。如果只是单线程场景,老实用 std::unordered_map 吧,毕竟这库的多线程优化带来的额外开销在单线程下并不划算。

小结

Image

parallel-hashmap 是个让人眼前一亮的库。既快,又省心,还免费(MIT 协议)。如果你的项目正被多线程的性能瓶颈折磨,不妨试试它,可能会让你感叹:原来并发哈希表还能这么玩!

Image

E

N

D

Image
Image

往期回顾

Image
Image

分享

Image

收藏

Image

在看

Image

点赞