C++ STL 原理与性能

一、先记住一句话

STL 性能 = 容器底层数据结构决定一切

你用什么容器,就注定了它的增删改查速度、内存占用、扩容成本


二、所有容器底层结构(必须背)

容器 底层结构 访问速度 插入/删除 适用场景
vector 动态数组 O(1)随机访问 尾部O(1),中间O(n) 多数场景、遍历快、连续内存
list 双向链表 O(n) 任意位置O(1) 频繁插入删除、不随机访问
deque 多段数组 O(1) 头尾O(1) 双端队列
stack/queue 适配器(deque/vector) O(1) 头尾O(1) 栈、队列
map/set 红黑树(平衡二叉树) O(log n) O(log n) 有序、快速查找
unordered_map 哈希表 O(1) O(1) 最快查找、无序
string 动态数组(char) O(1) 尾部O(1) 字符串

三、最核心容器原理精讲(带性能分析)

1. vector(最常用、最重要)

原理

  • 连续内存的动态数组
  • 满了就2倍扩容(1→2→4→8→16...)
  • 扩容 = 开辟新空间 + 拷贝所有元素 + 释放旧空间

性能关键点

  • 随机访问极快
  • 尾部插入
  • 中间/头部插入极慢(要移动元素)
  • 频繁扩容会造成性能损耗 + 内存碎片

优化技巧

cpp 复制代码
vector<int> v;
v.reserve(1000); // 预分配1000个空间,避免多次扩容!

2. list(双向链表)

原理

  • 非连续内存,每个节点存数据+前后指针
  • 不支持随机访问 v[5] ❌

性能

  • 任意位置插入/删除O(1)
  • 查找
  • 内存占用比 vector 大(存指针)

3. deque(双端队列)

原理

  • 多段连续内存拼接
  • 支持 [] 随机访问

性能

  • 头尾插入/删除O(1)
  • 中间插入

4. map / set(红黑树)

原理

  • 平衡二叉搜索树
  • key 自动有序

性能

  • 所有操作:O(log n)
  • 稳定、不丢数据、不会退化

5. unordered_map / unordered_set(哈希表)

原理

  • 哈希函数 + 数组 + 链表/红黑树
  • 无序

性能

  • 理论:O(1) 查找/插入
  • 哈希冲突时会变慢
  • 比 map 快很多

  • 遍历顺序不确定
  • 内存占用大

四、STL 性能对比(最实用)

查找速度

unordered_map(O(1)) > map(O(log n)) > vector(O(n))

插入速度(尾部)

vector ≈ unordered_map > map > list

插入速度(中间)

list > deque > vector

内存占用

list > unordered_map > map > vector


五、企业级性能优化黄金法则

1. 优先用 vector!

90% 场景 vector 最快。

2. 需要快速查找用 unordered_map

需要有序用 map。

3. 提前 reserve 空间

vector / string 大量插入前:

cpp 复制代码
v.reserve(n);

4. 少用 vector 头部插入

cpp 复制代码
v.insert(v.begin(), x); // 慢!

5. 遍历用 & 引用避免拷贝

cpp 复制代码
for(auto& x : vec) // 加&性能翻倍

6. 别频繁创建销毁容器

会反复申请释放内存。


六、面试必问 10 题(答案直接背)

  1. vector 扩容机制?
    满了2倍扩容,拷贝元素。
  2. vector 和 list 区别?
    连续内存 vs 链表,访问快 vs 插入快。
  3. map 和 unordered_map 区别?
    红黑树有序O(logn) vs 哈希表无序O(1)。
  4. vector 为什么快?
    连续内存 → CPU缓存命中高。
  5. reserve() 和 resize() 区别?
    reserve改容量,resize改大小。
  6. string 底层?
    动态数组。
  7. deque 原理?
    多段数组。
  8. 红黑树特点?
    自平衡、有序、稳定O(logn)。
  9. 哈希表冲突怎么办?
    链地址法/红黑树。
  10. STL 哪种容器最快?
    分场景:遍历vector,查找unordered_map。

七、总结(背会这一段就够)

  • vector:连续内存,随机访问快,尾部插入快,中间慢。
  • list:链表,插入删除快,查询慢。
  • map:红黑树,有序,O(logn)。
  • unordered_map:哈希表,最快查找,无序。
  • 性能关键:数据结构决定速度,预分配空间、少拷贝、少扩容。
相关推荐
码云数智-园园3 分钟前
类似小鹅通的知识付费小程序平台有哪些
开发语言
Darkwanderor10 分钟前
Linux线程控制
linux·c语言·c++
snow@li10 分钟前
Java:跨平台原理与JDK、JRE、JVM全景深度解析
java·开发语言·jvm
覆东流15 分钟前
2.Java程序基础
java·开发语言·后端
ttwuai22 分钟前
Go 后台定时任务启停不生效怎么办?先查调度同步链路
开发语言·后端·golang
小的~~33 分钟前
ThreadLocal 、InheritableThreadLocal 与 TransmittableThreadLocal 的进阶指南
java·开发语言
Darkwanderor39 分钟前
多线程的互斥问题和互斥锁解决互斥问题
linux·c语言·c++
键盘会跳舞40 分钟前
C++:std::pair 源码级深度剖析 —— 关联容器的基石
开发语言·c++·pair·关联容器
(Charon)43 分钟前
【C++】手写线程安全队列:mutex + condition_variable 实现生产者消费者模型
c语言·开发语言·c++
崖边看雾1 小时前
同步上下文管理器规则
开发语言·数据库