当前位置: 首页 > java >正文

std__map,std__unordered_map,protobuf__map之间的性能比较

简单比较下 std::map、std::unordered_map 和 protobuf::Map 的性能,主要关注在 插入、查找 和 删除 操作上的效率以及内存管理的差异。

std::map

  • 底层实现:std::map 使用红黑树作为底层数据结构,红黑树是一种平衡二叉查找树的变体结构,它的左右子树的高度差有可能会大于 1。所以红黑树不是严格意义上的平衡二叉树AVL,但对之进行平衡的代价相对于AVL较低, 其平均统计性能要强于AVL。红黑树具有自动排序的功能,因此它使得map也具有按key排序的功能,因此在map中的元素排列都是有序的。在map中,红黑树的每个节点就代表一个元素,因此实现对map的增删改查,也就是相当于对红黑树的操作。对于这些操作的复杂度都为O(logn),复杂度即为红黑树的高度。
  • 插入、查找、删除性能:由于是有序的,对于大数据量场景,树结构的操作时间更长。
  • 内存管理:std::map 内存占用较高,因为红黑树的每个节点都需要额外的指针存储,且树的平衡机制需要更多的内存管理。
  • 适用场景:显然std::map 适合需要数据有序存储的情况。

std::unordered_map

  • 底层实现:std::unordered_map 使用哈希表(hash table)作为底层数据结构,平均操作时间复杂度为 O(1),但最差情况下可能退化到 O(n)。key值是无序的。
  • 插入、查找、删除性能:在平均情况下,std::unordered_map 的性能通常优于 std::map,适合频繁的插入和查找操作。
  • 内存管理:哈希表在空间分配上通常会预分配一部分空间,以减少重哈希和再分配的频率。不过当哈希碰撞较多时,内存消耗会增加。
  • 适用场景:std::unordered_map 适合不关心顺序,但需要高效查找和插入操作的场景。

protobuf::Map

  • 底层实现:protobuf::Map 的具体实现网上搜索不到,但基于官方的Protobuf 文档(https://protobuf.dev/reference/cpp/api-docs/google.protobuf.map/), std::unordered_map,使用了哈希表来实现。
  • 插入、查找、删除性能:protobuf::Map 在 Protobuf 序列化、反序列化场景中的性能优于 std::map 和 std::unordered_map,因为它直接支持二进制序列化,减少了额外的序列化和转换成本。
  • 内存管理:protobuf::Map 为序列化和反序列化进行内存管理优化,减少了 Protobuf 数据格式和 C++ 容器之间的冗余转换,因此在存储大数据集或频繁数据交换时,内存消耗更低。
  • 适用场景: 相比 std::map 和 std::unordered_map,对于不在乎顺序的场景而言,protobuf::Map 与 std::unordered_map性能差不多,但考虑到序列化时间和内存占用,直接使用protobuf::Map可能会比较合适。

参考资料

  • https://protobuf.dev/reference/cpp/api-docs/google.protobuf.map/
  • https://stackoverflow.com/questions/3902644/choosing-between-stdmap-and-stdunordered-map
  • https://www.geeksforgeeks.org/map-vs-unordered_map-c/
  • https://medium.com/@yakupcengiz/comparing-std-map-and-std-unordered-map-in-c-92aa18c5dc39
  • chatgpt answer:
http://www.xdnf.cn/news/12248.html

相关文章:

  • 网页显示:嗯…无法访问此页面,的解决办法和原理
  • 大模型学习
  • 家政维修平台实战14登录验证
  • 如何用 SD-WAN 打破 ERP 内网限制,实现随时随地高效访问?
  • 总结HTML中的文本标签
  • 危化工厂部署人员定位系统的重要性
  • 算法性能分析
  • 智慧赋能:移动充电桩的能源供给革命与便捷服务升级
  • TripGenie:畅游济南旅行规划助手:个人工作纪实(九)
  • Linux 下生成动态库时 -fPIC的作用详解
  • 一些常用的JavaScript简写技巧
  • 如何利用Facebook优化TikTok的跨境商品推广效果
  • STM32 NVIC中断控制器
  • 【Algorithm】Union-Find简单介绍
  • 【Docker管理工具】部署Docker可视化管理面板Dpanel
  • [Java 基础]数组
  • 8086的简化版8088
  • PublishSubject、ReplaySubject、BehaviorSubject、AsyncSubject的区别
  • B+树知识点总结
  • Python训练营打卡Day45
  • Java高级 | 【实验五】Spring boot+mybatis操作数据库
  • 【网络安全】XSS攻击
  • Docker 与容器技术的未来:从 OCI 标准到 eBPF 的演进
  • EFI(x64)简易开发环境
  • 第七十四篇 高并发场景下的Java并发容器:用生活案例讲透技术原理
  • 一个基于Java的简单抢单功能实现示例,模拟多线程环境下的并发抢单场景
  • 【运维心得】内存占用虚标真相
  • ES6模块化
  • Java并发编程实战 Day 9:锁优化技术
  • `sendto()` / `recvfrom()` - 发送/接收数据(UDP)