STL容器 vector,list,deque 性能比较

PCIe设备内存访问实战:从ioremap到DMA映射的完整流程解析 本文深入解析了PCIe设备内存访问的完整流程,涵盖从CPU通过ioremap访问设备寄存器,到设备通过DMA映射高效读写主机内存的核心机制。详细探讨了虚拟地址、物理地址与总线地址的转换关系,对比了一致性与流式DMA映射的适用场景及同步要点,并阐述了IOMMU在安全与效率中的作用,为驱动开发者提供了实战代码与关键陷阱分析。 阅读详情
目录(?) [+]
    1. vector - 会自动增长的数组
    2. list - 擅长插入删除的链表
    3. deque - 拥有vector和list两者优点的双端队列
    4. 性能竞技场
    5. 性能总结与使用建议
    6. 测试程序清单

转载:http://www.cppblog.com/sailing/articles/161659.html

STL容器类vector,list,deque的比较
作者:斑鸠
更新时间:2009/01/04
编译器版本:Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86

C++的STL模板库中提供了3种容器类:vector,list,deque
对于这三种容器,在觉得好用的同时,经常会让我们困惑应该选择哪一种来实现我们的逻辑。
在少量数据操作的程序中随便哪一种用起来感觉差别并不是很大,
但是当数据达到一定数量后,会明显感觉性能上有很大差异。

本文就试图从介绍,以及性能比较两个方面来讨论这个问题。

  1. vector - 会自动增长的数组
  2. list - 擅长插入删除的链表
  3. deque - 拥有vector和list两者优点的双端队列
  4. 性能竞技场
  5. 性能总结与使用建议
  6. 测试程序清单

vector - 会自动增长的数组

vector又称为向量数组,他是为了解决程序中定义的数组是
不能动态改变大小这个缺点而出现的。
一般程序实现是在类创建的时候同时创建一个定长数组,
随着数据不断被写入,一旦数组被填满,则重新开辟一块更大的内存区,
把原有的数据复制到新的内存区,抛弃原有的内存,如此反复。

由于程序自动管理数组的增长,对于我们程序员来说确实轻松了不少,
只管把数据往里面插就行了,当然把物理内存和虚拟内存插爆掉了
就是操作系统来找你麻烦了:-)

vector由于数组的增长只能向前,所以也只提供了后端插入和后端删除,
也就是push_back和pop_back。当然在前端和中间要操作数据也是可以的,
用insert和erase,但是前端和中间对数据进行操作必然会引起数据块的移动,
这对性能影响是非常大的。

对于所有数组来说,最大的优势就是随机访问的能力。
在vector中,提供了at和[]运算符这两个方法来进行随机访问。
由于每个数据大小相同,并且无间隔地排列在内存中,
所以要对某一个数据操作,只需要用一个表达式就能直接计算出地址:
address = base + index * datasize

同样,对vector进行内存开辟,初始化,清除都是不需要花大力气的,
从头到尾都只有一块内存。

list - 擅长插入删除的链表

有黑必有白,世界万物都是成对出现的。
链表对于数组来说就是相反的存在。
数组本身是没有动态增长能力的(程序中也必须重新开辟内存来实现),
而链表强悍的就是动态增长和删除的能力。
但对于数组强悍的随机访问能力来说的话,链表却很弱。

list是一个双向链表的实现。
为了提供双向遍历的能力,list要比一般的数据单元多出两个指向前后的指针。
这也是没办法的,毕竟现在的PC内存结构就是一个大数组,
链表要在不同的环境中实现自己的功能就需要花更多空间。

list提供了push_back,push_front,pop_back,pop_front四个方法
来方便操作list的两端数据的增加和删除,不过少了vector的at和[]运算符的
随机访问数据的方法。并不是不能实现,而是list的设计者
并不想让list去做那些事情,因为他们会做得非常差劲。

对于list来说,清除容器内所有的元素是一件苦力活,
因为所有数据单元的内存都不连续,list只有一个一个遍历来删除。

deque - 拥有vector和list两者优点的双端队列

黑与白,处于这两个极端之间的就是令人愉悦的彩色了。
deque作为vector和list的结合体,确实有着不凡的实力。

STL的deque的实现没有怎么去看过,不过根据我自己的猜测,
应该是把数组分段化,在分段的数组上添加指针来把所有段连在一起,
最终成为一个大的数组。

deque和list一样,提供了push_back,push_front,
pop_back,pop_front四个方法。可以想象,如果要对deque的两端进行操作,
也就是要对第一段和最后一段的定长数组进行重新分配内存区,
由于分过段的数组很小,重新分配的开销也就不会很大。

deque也和vector一样,提供了at和[]运算符的方法。
要计算出某个数据的地址的话,虽然要比vector麻烦一点,
但效率要比list高多了。
首先和list一样进行遍历,每次遍历的时候累积每段数组的大小,
当遍历到某个段,而且baseN <= index < baseN + baseN_length的时候,
通过address = baseN + baseN_index就能计算出地址
由于分过段的后链表的长度也不是很长,所以遍历对于
整体性能的影响就微乎其微了。

看起来deque很无敌吧,不过deque和希腊神话的阿吉里斯一样,
再怎么强大也是有自己的弱点的,之后的测试数据中就能看到了。

P.S.请搜索「阿吉里斯的脚后跟」来获取详细内容

性能竞技场

为了能更好地进行比较,我们让静态数组(程序中写死的)和
动态数组(程序中new出来的)也参加了部分竞技。

竞技项目:
  •  初始化:对于静态和动态数组,逐一赋值,对于容器,push_back插入
  • 前向遍历:从0到n-1,每个数据自加1
  • 后向遍历:从n-1到0,每个数据自减1
  • 随机访问:在0到n-1中,随机抽取一定数量的数据进行读取
  • 后端插入:用push_back在后端插入一定数量的数据
  • 后端移除:用pop_back在后端移除一定数量的数据
  • 前端插入:用push_front在前端插入一定数量的数据
  • 前端移除:用pop_front在前端移除一定数量的数据
  • 中间插入:用insert在中间插入一定数量的数据
  • 中间移除:用erase在中间移除一定数量的数据
  • 反初始化:对于静态和动态数组,ZeroMemory删除所有数据,对于容器,调用clear方法
规则:
  • vector,list,deque都调用默认的构造函数来创建
  • 数组和容器的数据项都是1,000,000个
  • 前端和后端插入的数据项是10,000个
  • 前端和后端删除的数据项是10,000个
  • 随机访问的数据项是10,000个
  • 数据类型采用int型
  • 计时采用RDTSC高精度计时器来计时
  • 随机访问的数据的位置序列在测试前随机生成,所有数组和容器都采用这个序列
  • 测试采用Debug版(Release版会对代码进行优化,可能会对测试产生一定的影响)
  • 测试3次,取平均值
测试机配置:
Intel(R) Core(TM)2 CPU T7400 2.16GHz 2.16GHz
2.00GB内存

测试结果:(单位 秒)
测试项目静态数组动态数组vectorlistdeque备注
初始化0.005510.004610.2071.300.352list每个数据项都有附加数据,速度稍慢了一些
前向遍历0.003810.005490.07960.07560.0713 
后向遍历0.004220.004780.8850.8790.690 
随机访问0.0003340.0003420.001191480.0115list把时间都耗在了找寻相应数据上
后端插入N/AN/A0.001920.01280.00260 
后端移除N/AN/A0.001310.02930.00194 
前端插入N/AN/A10.20.01280.00547vector对前端操作很苦手啊
前端移除N/AN/A10.30.02970.00135同上
中间插入N/AN/A195187764看似万能的deque的最大弱点,因为复杂的结构导致中间数据操作带来的复杂性大大增加,体现在操作时间是其他两个的几倍
中间移除N/AN/A195209753同上
反初始化0.001390.002900.00001060.6930.305vector貌似是直接抛弃内存的,其他两个就没那么简单了

性能总结与使用建议

测试项目静态数组动态数组vectorlistdeque
初始化★★★★★★★★★★★★★★☆★★★☆☆★★★★☆
前向遍历★★★★★★★★★★★★★★☆★★★★☆★★★★☆
后向遍历★★★★★★★★★★★★★★☆★★★★☆★★★★☆
随机访问★★★★★★★★★★★★★★☆★☆☆☆☆★★★☆☆
后端插入N/AN/A★★★★★★★★★☆★★★★★
后端移除N/AN/A★★★★★★★★★☆★★★★★
前端插入N/AN/A★★☆☆☆★★★★☆★★★★★
前端移除N/AN/A★★☆☆☆★★★★☆★★★★★
中间插入N/AN/A★★☆☆☆★★☆☆☆★☆☆☆☆
中间移除N/AN/A★★☆☆☆★★☆☆☆★☆☆☆☆
反初始化★★★★★★★★★★★★★★★★★★★☆★★★★☆

一些使用上的建议:
Level 1 - 仅仅作为Map使用:采用静态数组
Level 2 - 保存定长数据,使用时也是全部遍历:采用动态数组(长度一开始就固定的话静态数组也行)
Level 3 - 保存不定长数组,需要动态增加的能力,侧重于寻找数据的速度:采用vector
Level 3 - 保存不定长数组,需要动态增加的能力,侧重于增加删除数据的速度:采用list
Level 4 - 对数据有复杂操作,即需要前后增删数据的能力,又要良好的数据访问速度:采用deque
Level 5 - 对数据中间的增删操作比较多:采用list,建议在排序的基础上,批量进行增删可以对运行效率提供最大的保证
Level 6 - 上述中找不到适合的:组合STL容器或者自己建立特殊的数据结构来实现

测试程序清单

>>>main.cpp<<<
目标跟踪与视频时序分析基础 两帧均有目标,却因快速移动导致检测框无重叠,仅靠交并比(IoU)无法维持身份关联。本文通过手算与纯Python实现最小跟踪流程,揭示IoU仅为位置线索,不能应对快速位移或遮挡。实验表明,即使目标真实存在,低重叠也会触发新编号。强调跟踪需结合运动预测、外观特征与阈值验证,避免误判。 阅读详情

相关推荐

ANSYS_APDL实战入门——从零开始掌握模态分析

本文为ANSYS APDL模态分析实战入门指南,通过一个悬臂梁案例,手把手教你从零开始掌握APDL命令流。内容涵盖从模型创建、材料定义、网格划分到边界条件设置、求解及后处理结果查看的全流程,帮助工程师快速上手结构动力学分析,避免共振风险。

egg99的博客 1131

STL容器类vector,list,deque的比较

<br />STL容器类vector,list,deque的比较<br /> 作者:斑鸠<br /> 更新时间:2009/01/04<br /> 编译器版本:Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86<br /> C++的STL模板库中提供了3种容器类:vector,list,deque<br /> 对于这三种容器,在觉得好用的同时,经常会让我们困惑应该选择哪一种来实现我们的逻辑。<

冰雪八哥的专栏 1406

6G网络的关键技术、应用前景与挑战并存的科技征途

移动通信技术正以前所未有的速度迭代更新,而6G技术的研发进程渐渐成为了当前科技领域的热点。全球各国已纷纷将目光投向了充满想象的6G时代。本文将探讨全球6G技术研发的最新进展,以及6G技术的核心创新与潜在应用。

fiberroad的博客 2424

C++各个容器比较(vector,deque,list,set,map,queue,stack)

1、vector(连续的空间存储,可以使用[ ]操作符)可以快速的访问随机的元素,快速的在末尾插入元素,但是在序列中间随机的插入、删除元素要慢。而且,如果一开始分配的空间不够时,有一个重新分配更大空间的过程。     2、deque(小片的连续,小片间用链表相连,实际上内部有一个map的指针,因为知道类型,所以还是可以使用[ ],只是速度没有vector快)快速的访问随机的元素,快速的在开始和末

Lyu-ming 栏目 2399

SAP ABAP VL09 BAPI VL 216

ls_batch_item-fact_unit_denom = ls_lips_split-umvkn. "销售数量转换为 SKU 的值(分母)ls_batch_item-fact_unit_nom = ls_lips_split-umvkz. "销售数量转换成SKU的分子(因子)ls_batch_item-sales_unit_iso = ls_lips_split-meins. "被拆分DN基本单位。

ChampaignWolf的专栏 2300

BurpSuite+安卓模拟器双保险:避开真机抓包限制的完整配置指南

本文详细介绍了如何通过BurpSuite与安卓模拟器(如雷电、夜神)协同工作,绕过真机抓包限制的完整配置指南。从环境准备、网络拓扑配置到证书部署和流量分析,提供了一套高效的解决方案,帮助安全测试人员稳定捕获手机数据包,提升测试效率。

Apple的专栏 439

C++/C++11中std::deque的使用

C++/C++11中std::deque的使用

网络资源是无限的 4万+

保姆级教程:手把手教你从NASA Earthdata下载ASTER L2地表温度数据(附shp文件拖拽技巧)

本文提供了一份详细的NASA Earthdata平台ASTER L2地表温度数据下载教程,涵盖账号注册、数据筛选、shp文件拖拽技巧及质量检查等关键步骤。特别适合遥感领域初学者,帮助快速掌握高效获取ASTER L2T数据的方法,适用于城市热岛效应和农业监测等研究。

weixin_30736301的博客 470

[c++] queue和deque比较

1、queue 可以看到是从队首弹出,先入先出 并且queue只能从队首删除元素 2、deque 可以看到deque可以访问两端但是只能修改队头 而deque可以访问两端并且可以在队首和队尾删除和插入元素

观林望实的博客 1261

ros入门(八)---TF坐标转换

TF(TransForm),就是坐标转换,包括了位置和姿态两个方面的变换。

weixin_51157015的博客 3388

数学建模学习(78):多输入多输出回归预测模型(结合XGBoost实现)

多输入多输出回归预测问题求解

全栈川川 8131

C++ 之 deque

deque特性迭代器小结 特性 deque是双端队列不规则的首字母缩写,双端队列是动态大小的序列式容器,其可以向两端进行伸缩。 特定的库可以以不同的方式实现deque,但通常都是一种动态数组。不论在何种情况下,它都允许通过随机访问迭代器直接访问单个元素,可以根据需要动态的伸缩。 因此,deque提供了一些与vector相似的功能,但deque在头部和尾部进行数据插入和删除操作更加高效。 与ve...

giturtle's blog 486

阅文集团大数据面试题及参考答案

在 Flink 中,watermark 是一种用于处理乱序事件时间的机制。实现接口:通常需要实现 AssignerWithPeriodicWatermarks 或 AssignerWithPunctuatedWatermarks 接口。前者会周期性地生成 watermark,后者则是基于某些特定事件来生成 watermark ,比如接收到某个特定值的消息时。定义位置:可以在数据源处或者在流处理的中间操作中定义 watermark。在数据源定义时,能更精准地根据数据的产生特性设置 watermark;

大模型大数据攻城狮的专栏 1089

STL容器类vector,list,deque性能的比较

http://hi.baidu.com/shirley_wheat/blog/item/84a3b5f59389eb61dcc47441.html   C++的STL模板库中提供了3种容器类:vector,list,deque 对于这三种容器,在觉得好用的同时,经常会让我们

ATMCash4423的专栏 1108

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

vector、list、deque的差异

适配器是一种封装底层容器的设计模式,目的是提供统一的访问接口,同时屏蔽底层容器的实现细节。例如std::queue(队列)和std::stack(栈)是典型的适配器,它们默认以std::deque作为底层容器。

2401_87727424的博客 1195

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

从看懂到看开:c++的实用容器list的讲解与模拟实现

1.list是在常数范围内在任意位置进行插入删除的序列容器,并且该容器可以实现双向迭代2.list类的底层是双向带头循环链表结构,每个元素都存储在互不相关的独立节点中,每个节点都有指向其前后节点的指针3.该类与forward_list非常相似,但后者是单链表,适用性不如list类4.与vector,array,deque相比,list通常在任意位置插入和删除的效率更好。

whcwhc111111的博客 1591

C++ stack容器选型指南:3分钟搞懂deque、vector、list的取舍

3分钟掌握C++ STL stack底层容器选择技巧,详解deque、vector、list的性能差异与适用场景。默认deque兼顾效率与扩展性,vector适合固定容量,list支持频繁插入。选型方法一目了然,值得收藏。

QuickDebug的博客 386

C++ - STL常见容器及其常见操作

本文主要记录一下STL中一些常见的容器(包括vector、deque、queue、list、stack、set、map),及其对应的常见的操作,不涉及更深层次原理性的知识。方便以后使用、查阅。

bailang_zhizun的博客 2318

STL学习笔记

1.     STL容器简介 STL(Standard Template Library,标准模板库)从根本上说,是一些算法、容器的集合,STL可以让你重复运用既有的算法,而不必在环境类似的情况下再撰写相同的代码。STL算法是泛型的,不与任何特定数据结构或对象型别系缚在一起,但是却像为你量身定做的一样,有很高的效率。STL甚至是可扩充的,就像STL组件彼此之间可以相互配合运用一样,STL组件也可

Always look out for number one. 863

stl容器区别: vector list deque set map及底层实现

在STL中基本容器有: vector、list、deque、set、map set 和map都是无序的保存元素,只能通过它提供的接口对里面的元素进行访问 set:集合, 用来判断某一个元素是不是在一个组里面,使用的比较少map:映射,相当于字典,把一个值映射成另一个值,如果想创建字典的话使用它好了底层采用的是树型结构,多数使用平衡二叉树实现,查找某一值是常数时间,遍历起来效果也...

weixin_30876945的博客 82

Effective STL 第1条:慎重选择容器类型。

STL(标准模板库)提供了多种容器类型,每种容器在性能、内存占用和适用场景上各有优劣。选择合适的容器类型是高效使用STL的第一步。以下从容器分类、性能分析和实际场景出发,详细探讨如何选择最合适的容器。| 容器 | 随机访问 | 插入/删除(头部) | 插入/删除(尾部) | 中间插入/删除 |支持O(1)随机访问,但。在尾部插入效率更高,而。

dUN_wfee的博客 293

C++ 的容器适配器——从stack/queue看

适配器的作用是“将一个类的接口转换为客户希望的另一个接口”。stack:只允许在一端插入/删除;queue:允许在一端入、一端出(FIFO)。适配器并不自己管理内存,而是复用底层容器(dequevectorlist等)。理解容器适配器的核心在于“接口的封装”和“底层容器的选择”。实现时应注意模板默认参数写法、成员函数的 const/ noexcept 语义与空容器的边界条件。通过上述改进可以让自实现的stack更安全、更 STL 风格、更易于扩展。

2401_87287423的博客 478
上一篇: BSTR、LPSTR、LPWSTR、CString、VARIANT、COleVariant 、_variant_t、CComBSTR、_bstr_t
下一篇: VS2005,VS2008,VS2010工程文件和解决方案的区别
erick08
博客等级 码龄18年 24粉丝 16原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值