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:哈希表,最快查找,无序。
  • 性能关键:数据结构决定速度,预分配空间、少拷贝、少扩容。
相关推荐
码不停蹄的玄黓1 小时前
Java线程池生命周期
java·开发语言
Kingairy1 小时前
LUA环境搭建
开发语言·lua
小欣加油1 小时前
leetcode239 滑动窗口最大值
数据结构·c++·算法·leetcode·哈希算法
z落落1 小时前
C# 虚方法(virtual)与抽象方法 +区别+new方法隐藏 & override方法重写
java·开发语言·c#
玖釉-1 小时前
Vulkan 示例解析:pipelines.cpp 如何在一个 Render Pass 中切换多条 Graphics Pipeline
c++·windows·算法·图形渲染
Ada's1 小时前
【计算机基础系列】python语言:环境搭建
开发语言·python
xiaoshuaishuai81 小时前
C# Avalonia UI的ItemControl
开发语言·ui·c#
未若君雅裁1 小时前
JMM、volatile 与 CAS:并发安全三大问题
java·开发语言
hai3152475431 小时前
# 矩阵算法·算子对齐工具 v6.1 — 技术规格与使用手册
java·开发语言·驱动开发·神经网络·spring·目标检测·矩阵