文章目录

    • 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.pswp.cn/pingmian/95444.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/95444.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/95444.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

自学嵌入式第三十四天:网络编程-TCP

一、UDP用户数据报收发次数要对应;数据与数据之间有边界,多次调用收发时都是不同的数据报;接收方的数据大小>发送方的数据大小,如果接受方数据小了则会丢弃未读的部分,再次调用只会读下一包数据;二、服务…

Apache IoTDB:国产时序数据库的崛起与工业物联网的未来

📑前言 在工业物联网的浪潮中,数据不再是副产品,而是驱动决策的核心资产。"随着物联网、工业互联网和智能监控的迅猛发展,时序数据正以前所未有的速度爆发。据预测,到2025年全球物联网设备将达750亿台&#xff0c…

一键核验,安全无忧!手机号三要素详情版API,为您的业务筑牢身份认证防线

一、什么是手机号三要素核验API? 手机号三要素核验API 是一种通过编程接口,实时验证一条个人身份信息是否与该国运营商登记的实名信息一致的在线服务。 这里的“三要素”特指: 姓名 身份证号码 手机号码 核验过程:用户提交上述三个…

轻松上手 qData 数据中台开源版:Docker Compose 助你10分钟跑起来

说在前面 谁适合看这份指南? 初次接触 qData,希望快速体验功能的小伙伴不想折腾复杂环境配置和前端打包的人想用“一键启动”省事体验完整平台的用户 我们已经为你准备好“开箱即用”的完整部署包,包括: ✅ 前端静态资源&…

Qt读写Excel--QXlsx基本使用

1、概述 Document 类是一个用于操作 XLSX 文件的类,继承自 QObject。它提供了对 Excel 文件的读写操作,包括单元格的读写、图片和图表的插入、单元格合并、列和行的格式化、数据验证和条件格式化等功能。此外,它还支持对工作簿和工作表的操作…

P13929 [蓝桥杯 2022 省 Java B] 山 题解

缩减一下题目的意思,问区间 [2022,2022222022] 有多少个数是回文数并且先单调不减,后单调不增。 因为有这两条条件,我们可以得知在判断时只用判断前半段的每个数是不是和对面相应的位置相等,以及是否单调不减。 为什么不用看后半段…

Unity Android 文件的读写

配置AndroidManifest 文件在Assets 目录下查找AndroidManifest 文件&#xff0c;添加权限声明&#xff0c;在application 节点中添加requestLegacyExternalStorage 属性。<!-- 权限声明 --> <uses-permission android:name"android.permission.READ_EXTERNAL_STO…

Pydantic模型验证测试:你的API数据真的安全吗?

url: /posts/03b2afdf35f55dbaef631710ab6da82c/ title: Pydantic模型验证测试:你的API数据真的安全吗? date: 2025-09-03T23:46:18+08:00 lastmod: 2025-09-03T23:46:18+08:00 author: cmdragon summary: Pydantic在FastAPI中用于数据验证和序列化,通过Python类型注解自动…

【Proteus仿真】AT89C51单片机中断系列仿真——INT0中断控制LED小灯/INT0和INT1中断控制数码管

目录 0案例视频效果展示 0.1例子1&#xff1a;INT0控制LED闪烁 0.2例子2&#xff1a;INT0中断控制数码管计数 0.3例子3&#xff1a;INT0中断实现秒表功能 0.4例子4&#xff1a;INT0INT1中断控制数码管计数 1基础知识补充——中断系统 1.1 中断源一览 1.2 控制寄存器 1…

MTK Linux DRM分析(三十三)- MTK mtk_mipi_tx.c

一、MIPI PHY驱动简介 1. MIPI 协议分层 应用层:显示(DSI)、摄像头(CSI)。 协议层:定义像素/图像帧如何封装成数据包。 物理层(PHY):具体电气信号传输方式 —— 这里就是 D-PHY 或 C-PHY。 2. D-PHY(Differential PHY) 传输方式:差分信号(类似 LVDS/USB/PCIe …

G2D 图形加速器

文章目录G2D 图形加速器1. 功能简介1.1 矩形填充1.2 旋转和镜像 (rotate and mirror)1.3 透明度混合1.4 colorkey1.5 缩放 (Stretchblt)2. G2D 框架3. 全志 G2D 使用示例3.1 使用G2D实现图像旋转缩放3.2 实时预览中加入旋转缩放功能G2D 图形加速器 G2D模块主要实现图像旋转、数…

【FPGA】单总线——DS18B20

目录 项目&#xff1a;项目&#xff08;含quartus工程、仿真文件&#xff09; 1. 单总线通信时序详解 1.1 初始化&#xff08;复位脉冲 存在脉冲&#xff09; 1.2 写时隙&#xff08;写“0”和写“1”&#xff09; 1.3 读时隙 2. DS18B20 暂存器与温度数据格式 2.1 暂存…

JUC的安全并发包机制

目录 1. Lock机制&#xff1a;明锁控制 2. 栅栏机制(CyclicBarrier) 3. 闭锁机制(CountDownLatch) 4. 信号量机制(Semaphore) 5. 无锁机制 1. Lock机制&#xff1a;明锁控制 Lock接口提供了比synchronized更灵活的锁机制&#xff0c;属于明锁&#xff08;需要手动获取和释…

开源企业级快速开发平台(JeecgBoot)

JeecgBoot 是一款基于 Spring Boot Vue 技术栈的开源企业级快速开发平台&#xff0c;旨在通过「低代码代码生成」模式降低企业级应用的开发成本&#xff0c;提升开发效率。其核心定位是“开箱即用的中后台解决方案”&#xff0c;覆盖权限管理、表单报表、工作流、代码生成等核…

探索 PostgreSQL 和 MySQL 之间的主要差异和相似之处,找到满足您项目需求的最佳数据库解决方案。

探索 PostgreSQL 和 MySQL 之间的主要差异和相似之处&#xff0c;找到满足您项目需求的最佳数据库解决方案。 探索 PostgreSQL 和 MySQL 之间的主要差异和相似之处&#xff0c;找到满足您项目需求的最佳数据库解决方案。 关系数据库已经存在了很长时间。事实上&#xff0c;关系…

如何画时序图、流程图、状态流转图

如何画时序图、流程图、状态流转图流程图符号约定时序图元素交互框最佳实践状态流转图在研发或者写技术方案的时候&#xff0c;我们经常会画各种图。图比文字更加容易理解一些&#xff0c;那么如何画出优秀好看的图呢下面简单介绍一些画图时需要注意的点 流程图 流程图是流程…

CSDN 与 掘金 高效学习指南

CSDN 和掘金&#xff08;juejin.cn&#xff09;是国内最活跃的技术社区&#xff0c;但信息量巨大、质量参差不齐。高效运用的关键是&#xff1a;从“被动浏览”转向“主动获取”&#xff0c;避免陷入“收藏一堆文章却学不会”的陷阱。 以下是为你量身定制的CSDN 与 掘金 高效学…

容器tomcat镜像制作

pull-tomcat镜像 docker pull tomcat启动 –security-opt 禁用默认的安全策略&#xff0c;放宽限制 docker run -d --name mysql-tomcat -p 8080:8080 --security-opt seccompunconfined tomcat:latest进入容器直接访问404&#xff0c;网页相关的webapps下面为空&#xff0c;将…

AC安全认证方式全解析

AC的几种安全认证方法认证方式 安全性 便捷性 典型应用场景 所需配置Portal认证 ​​中 高 访客网络、商场、 Portal服务 酒…

《垒球江西百科》男子垒球世界纪录·垒球9号位

男子垒球世界纪录终极盘点⚾ | 冷知识科普&#xff01;1. 最远本垒打距离 | Longest Home Run Distance纪录保持者&#xff1a; Jeff Hall (美国)距离&#xff1a; 643英尺 (约196米)赛事&#xff1a; 2012年 USSSA 慢投垒球锦标赛✨ 科普&#xff1a; 慢投垒球中&#xff0c;球…