登录
/
注册
首页
论坛
其它
首页
科技
业界
安全
程序
广播
Follow
关于
签到
每天签到奖励2-10圆
导读
排行榜
TG频道
发帖说明
登录
/
注册
账号
自动登录
找回密码
密码
登录
立即注册
搜索
搜索
关闭
CSDN热搜
程序园
精品问答
技术交流
资源下载
本版
帖子
用户
软件
问答
教程
代码
写记录
VIP申请
VIP网盘
网盘
联系我们
发帖说明
每日签到
道具
勋章
任务
淘帖
动态
分享
留言板
导读
设置
我的收藏
退出
腾讯QQ
微信登录
返回列表
首页
›
业界区
›
安全
›
打破迷思:为什么资深C++开发者几乎总是选择vector而非l ...
打破迷思:为什么资深C++开发者几乎总是选择vector而非list
[ 复制链接 ]
后沛若
2025-6-1 21:07:14
大家好,我是小康。
前言:打破你对容器选择的固有认知
嘿,C++小伙伴们!面对这段代码,你会怎么选?
// 存储用户信息,需要频繁查找、偶尔在中间插入删除
// 选择哪个容器实现?
std::vector<UserInfo> users; // 还是
std::list<UserInfo> users; // ?
复制代码
如果你刚学习C++,可能会想:"数据会变动,肯定用list啊!教材上说链表插入删除快嘛!"
然后有一天,你看到一位经验丰富的同事把所有list都改成了vector,并且代码性能提升了,你一脸懵逼: "这跟我学的不一样啊!"
是的,传统教科书告诉我们
:
数组(vector):随机访问快,插入删除慢
链表(list):插入删除快,随机访问慢
但实际工作中,大多数资深C++开发者却几乎总是使用vector。为什么会这样?是教材错了,还是大佬们有什么不可告人的秘密?
今天,我要带你进入真实的C++江湖,揭开vector和list性能的真相,帮你彻底搞懂这个看似简单却被无数程序员误解的选择题。
深入阅读后,你会发现:这个选择背后,涉及现代计算机体系结构、内存模型和真实世界的性能考量,而不仅仅是算法复杂度的简单对比。
微信搜索 【
跟着小康学编程
】,关注我,定期分享计算机编程硬核技术文章。
一、理论上:vector和list各是什么?
先来个直观的比喻
:
vector就像一排连续的座位
:大家坐在一起,找人超快,但中间插入一个人就需要后面的人都往后挪。
list就像一群手拉手的人
:每个人只知道自己左右邻居是谁,找到第n个人必须从头数,但中间插入一个人只需要改变两边人的"指向"。
技术上讲
:
vector
:连续内存,支持随机访问(可以直接访问任意位置),内存布局紧凑
list
:双向链表,只支持顺序访问(必须从头/尾遍历),内存布局分散
vector和list的内部结构对比
vector的内部结构
:
[元素0][元素1][元素2][元素3][元素4][...]
↑ ↑
begin() end()
复制代码
vector内部其实就是一个动态扩展的数组,它有三个重要指针:
指向数组开始位置的指针start
指向最后一个元素后面位置的指针end
指向已分配内存末尾的指针(容量capacity)
当空间不够时,vector会重新分配一块更大的内存(通常是当前大小的1.5或2倍),然后把所有元素搬过去,就像搬家一样。
list的内部结构
:
┌──────┐ ┌──────┐ ┌──────┐
│ prev │◄───┤ prev │◄───┤ prev │
┌──┤ data │ │ data │ │ data │
│ │ next │───►│ next │───►│ next │
│ └──────┘ └──────┘ └──────┘
│ 节点0 节点1 节点2
↓
nullptr
复制代码
list是由一个个独立的节点组成,每个节点包含三部分:
存储的数据
指向前一个节点的指针
指向后一个节点的指针
这就像一个手拉手的圆圈游戏,每个人只能看到左右两个人,要找到第五个人,必须从第一个开始数。
这两种容器结构上的差异,决定了它们在不同操作上的性能表现。vector因为内存连续,所以可以通过简单的指针算术直接跳到任意位置;而list必须一个节点一个节点地遍历才能到达指定位置。
按照传统教科书,它们的复杂度对比是这样的
:
操作vectorlist随机访问O(1)O(n)头部插入/删除O(n)O(1)尾部插入/删除均摊 O(1)O(1)中间插入/删除O(n)O(1)**
注意
:list 的中间插入/删除是O(1),但前提是你已经有了指向该位置的迭代器,找到这个位置通常需要O(n)时间。
看上去 list 在插入删除方面优势明显,但为什么那么多经验丰富的程序员却建议"几乎总是用vector"呢?
二、现实很残酷:理论≠实践
老铁,上面的理论分析忽略了一个超级重要的现代计算机特性:
缓存友好性
。
什么是缓存友好性?
想象你去图书馆看书:
vector就像是把一整本书借出来放在你桌上(数据连续存储)
list就像是每看一页就得去书架上找下一页(数据分散存储)
现代CPU都有缓存机制,当访问一块内存时,会把周围的数据也一并加载到缓存。对于连续存储的vector,这意味着一次加载多个元素;而对于分散存储的list,每次可能只能有效加载一个节点。
实际性能测试
我做了一个简单测试,分别用vector和list存储100万个整数,然后遍历求和:
// Vector遍历测试 - 使用微秒计时更精确
auto start = chrono::high_resolution_clock::now();
int sum_vec = 0;
for (auto& num : vec) {
sum_vec += num;
}
auto end = chrono::high_resolution_clock::now();
auto vector_time = chrono::duration_cast<chrono::microseconds>(end - start).count();
// List遍历测试 - 使用微秒计时更精确
start = chrono::high_resolution_clock::now();
int sum_list = 0;
for (auto& num : lst) {
sum_list += num;
}
end = chrono::high_resolution_clock::now();
auto list_time = chrono::duration_cast<chrono::microseconds>(end - start).count();
// 输出结果 - 微秒显示,并转换为毫秒显示
....
复制代码
结果震惊了我
:
这是30几倍的差距!为啥?就是因为缓存友好性!
三、list的"快速插入"真的快吗?
我们再来测试一下在容器中间位置插入元素的性能:
[code] cout
打破
迷思
为什么
资深
开发者
相关帖子
为什么不该用 Double 表示金额及解决方案
我为什么认为未来的自动化应该是:人提需求,AI生成工作流,AI工具执行
PHP 开发者应该理解的 Linux 入门权限指南
学习unigui【38】重新认识UUNIGUI--为什么这样快? 站在“架构与性能”层面重新审视
为什么RAG技术可以缓解大模型知识固化和幻觉问题
华为开发者空间携手乐知行:轻松实现智能网联小车数据可视化系
重磅!Java开发者的春天来了,Cursor组建专项团队解决Java开发痛点!
为什么下载小电影时,进度总是卡在99%?
【活动预告】2025斗拱开发者大会,共探支付与AI未来
【光照】UnityURP为什么要[Gamma矫正]?
vip免费申请,1年只需15美金$
回复
使用道具
举报
提升卡
置顶卡
沉默卡
喧嚣卡
变色卡
千斤顶
照妖镜
相关推荐
业界
为什么不该用 Double 表示金额及解决方案
0
708
翱龟墓
2025-10-10
业界
我为什么认为未来的自动化应该是:人提需求,AI生成工作流,AI工具执行
0
160
栓汨渎
2025-10-12
业界
PHP 开发者应该理解的 Linux 入门权限指南
0
574
布相
2025-10-12
安全
学习unigui【38】重新认识UUNIGUI--为什么这样快? 站在“架构与性能”层面重新审视
0
793
黎娅茜
2025-10-13
业界
为什么RAG技术可以缓解大模型知识固化和幻觉问题
1
250
嗳诿
2025-10-13
业界
华为开发者空间携手乐知行:轻松实现智能网联小车数据可视化系
0
868
颜才
2025-10-14
安全
重磅!Java开发者的春天来了,Cursor组建专项团队解决Java开发痛点!
0
805
东郭欣然
2025-10-16
科技
为什么下载小电影时,进度总是卡在99%?
0
67
全叶农
2025-10-17
安全
【活动预告】2025斗拱开发者大会,共探支付与AI未来
0
742
敕码
2025-10-17
业界
【光照】UnityURP为什么要[Gamma矫正]?
0
523
米嘉怡
2025-10-18
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
|
立即注册
回复
本版积分规则
回帖并转播
回帖后跳转到最后一页
签约作者
程序园优秀签约作者
发帖
后沛若
2025-6-1 21:07:14
关注
0
粉丝关注
23
主题发布
板块介绍填写区域,请于后台编辑
财富榜{圆}
anyue1937
9994893
dage888
999994
3934307807
992122
4
富账慕
9977
5
邹语彤
9979
6
二艰糖
9997
7
刎唇
9993
8
匝抽
9986
9
聚怪闩
9960
10
孙淼淼
9977
查看更多