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

C++知识

文章目录

    • 1.C++map为什么线程不安全?
    • 2.map大量插入会有性能问题,为什么
    • 3.set的应用场景
    • 4.map set mutiset mutimap unordered_map unordered_set的底层实现、使用场景、优缺点

1.C++map为什么线程不安全?

其实STL中的容器都是线程不安全的,如果想要线程安全的话,就得自己加锁。

C++ 标准库从 C++11 开始明确规定:多个线程并发地对同一个 std::map 对象进行读写操作,是未定义行为(UB)——除非你自己加锁(如 std::mutex)。

为什么 std::map 不自带锁?

  1. 性能优先
    标准库容器的设计哲学是零开销抽象(zero-overhead abstraction)。
    如果每个操作都加锁,即使单线程程序也会被迫承担锁的开销,这违背了 C++ 的设计原则。
  2. 灵活性更高
    用户可以根据具体场景选择锁的粒度(全局锁、分段锁、读写锁等)。
    标准库提供了 std::mutex、std::shared_mutex 等工具,让用户自己组合。

2.map大量插入会有性能问题,为什么

std::map 在“大量插入”场景下出现性能瓶颈,并不是因为它“不会用 CPU”,而是由它的底层数据结构(红黑树)和接口语义共同决定的。下面把原因拆成 4 个层面,一层层展开:
① 数据结构层面:红黑树的 O(log n) 代价
插入 = 搜索插入点 + 树重平衡。

每 insert/operator[] 都要从根节点一路比较到叶子,找到插入位置;随后可能触发 旋转 + 颜色翻转,这些都是 O(log n) 的 CPU 计算。

当 n 达到百万、千万级时,log₂(n) 依旧不算小,而且每一次操作都独立走一遍完整路径,CPU 分支预测失败率高、cache miss 高。

② 内存分配层面:节点级分配带来的负担

红黑树是 “节点式容器”(node-based container),每插入一个元素就至少一次 new/malloc。

大量小对象分配 →内存碎片;分配器锁竞争(默认 glibc ptmalloc 的 global arena 锁);cache locality 极差:节点散落在堆各处,遍历时随机访问,TLB & cache 命中率低。

③ 接口语义层面:每次插入都要“唯一键”检查

std::map::insert 和 operator[] 都要 先查重,保证键唯一。就算你事先知道键不会重复,也绕不开这次查找;而哈希表(unordered_map)可以通过 reserve + emplace_hint 避免重复检查。

④ 并发层面:自带无锁机制 → 线程竞争放大问题

如果你在多线程环境用全局 mutex 保护 std::map,锁粒度是整个对象;大量插入让这把锁成为 热点,线程上下文切换/睡眠开销迅速放大(之前谈过的互斥锁 vs 自旋锁问题)。

综合症状 = 计算 + 内存 + 并发 三重放大

维度开销来源量级
CPU红黑树 log n 比较 + 旋转10⁷ 次插入时 log₂(10⁷) ≈ 23
内存每元素一次 new + 指针开销额外 2~3 倍内存放大
并发全局 mutex 或分配器锁线程越多越慢

std::map 大量插入慢,是因为 “红黑树的节点级操作 + 每次 log n 计算 + 频繁内存分配” 三者叠加;把容器换成哈希表、把一次性插入变成批量构造,或者把 map 拆掉分片,都能让性能上一个数量级。

3.set的应用场景

需求容器
需要去重、有序遍历、范围查询是否存在std::set / std::multiset
只去重/查询、不关心顺序std::unordered_set(平均 O(1))
键可重复std::multisetunordered_multiset
极高并发读写第三方并发 set(tbb::concurrent_hash_set, folly::F14)

4.map set mutiset mutimap unordered_map unordered_set的底层实现、使用场景、优缺点

容器底层实现典型场景优点缺点
map红黑树键值对有序、范围查询、遍历有序、可范围遍历、最坏O(log n)内存碎片大、插入慢、cache差
set红黑树去重+有序遍历、排行榜有序、唯一键、支持lower_bound同map缺点
multiset红黑树允许重复键的有序集合保留排序、可存重复同map缺点
multimap红黑树一键多值的有序存储一键多值、范围遍历同map缺点
unordered_map哈希表键值对无序、高速增删查平均O(1)、内存连续性好无序、rehash开销、最坏O(n)
unordered_set哈希表高速去重、存在性检查平均O(1)、简单高效无序、rehash开销、最坏O(n)
http://www.dtcms.com/a/366749.html

相关文章:

  • C 盘清理技巧分享:释放磁盘空间,提升系统性能
  • 将 PDF 转换为 TIFF 图片:简单有效的 Java 教程
  • 数据传输,数据解析与写数据库
  • django全国小米su7的行情查询系统(代码+数据库+LW)
  • 阿瓦隆 A15 Pro 221TH/S:SHA-256 算力与高效能耗
  • 大模型部署全攻略:Docker+FastAPI+Nginx搭建高可用AI服务
  • Linux 编译 Android 版 QGroundControl 软件并运行到手机上
  • 一天涨幅2000倍的期权有吗?
  • (JVM)四种垃圾回收算法
  • ArcGIS学习-15 实战-建设用地适宜性评价
  • Node.js轻松生成动态二维码
  • Windows+Docker一键部署CozeStudio私有化,保姆级
  • 【Docker】P1 前言:容器化技术发展之路
  • LangChain4J-(4)-多模态视觉理解
  • 少儿编程C++快速教程之——2. 字符串处理
  • SMARTGRAPHQA —— 基于多模态大模型的PDF 转 Markdown方法和基于大模型格式校正方法
  • Unity之安装教学
  • GcWord V8.2 新版本:TOA/TA字段增强、模板标签管理与PDF导出优化
  • 无需任何软件禁用 10 年 windows 更新
  • ArcGIS答疑-如何消除两张栅格图片中间的黑缝
  • 《D (R,O) Grasp:跨机械手灵巧抓取的机器人 - 物体交互统一表示》论文解读
  • 零售消费企业的数字化增长实践,2025新版下载
  • 三目摄像头 是一种配备三个独立摄像头模块的视觉系统
  • 苍穹外卖Day9 | 用户端、管理端接口功能开发、百度地图解析配送范围
  • 算法之二叉树
  • 不用服务器也能监控网络:MyIP+cpolar让中小企业告别昂贵方案
  • Wisdom SSH 是一款集成了强大 AI 助手功能的 SSH 工具,助你高效管理服务器。
  • 以OWTB为核心的三方仓运配一体化平台架构设计文档V0.1
  • 【软件测试】第1章 认识测试
  • Qt实现2048小游戏:看看AI如何评估棋盘策略实现“人机合一