关于大量元素的list对象删除效率

paschen 版主 2015-08-27 08:30:41
类中使用了10个std::list<CString>,每个list又平均有数万个值

在类对象析构时要析构好几分钟

我知道效率偏低的原因再于反复delete很多元素,如果用vector就会快很多

可是由于需要迭代器不失效以及频繁插入数据,所以不想换成其他容器

我试过在析构时创建多个线程,每个线程分别执行一个list对象的clear操作,可速度并没有改善,不知是否是由于STL对多线程加了锁

故请教各位大神有没有不换成其他容器的情况下提高一点效率
...全文
592 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
paschen 版主 2015-08-28
  • 打赏
  • 举报
回复
引用 6 楼 jiqiang01234 的回复:
可以用boost::pool当做,std::list的分配器模板参数来试试
这个建议我试下
paschen 版主 2015-08-28
  • 打赏
  • 举报
回复
引用 7 楼 dengqibin 的回复:
vector会比list更快,这个很不解啊,vector是数组类型的,删除了会进行拷贝移位什么的,list是链表试的,只用改指针,被删除的元素,两个容器都要调他的析构函数,应该是一样的,你确定是由于容器不一样产生的性能差别?
我指的删除不是只删除一个元素,是清空所有元素,释放内存
paschen 版主 2015-08-28
  • 打赏
  • 举报
回复
引用 1 楼 ri_aje 的回复:
[quote=引用 楼主 paschen 的回复:] 我知道效率偏低的原因再于反复delete很多元素,如果用vector就会快很多 可是由于需要迭代器不失效以及频繁插入数据,所以不想换成其他容器
试过 std::deque 吗?
引用 楼主 paschen 的回复:
我试过在析构时创建多个线程,每个线程分别执行一个list对象的clear操作,可速度并没有改善,不知是否是由于STL对多线程加了锁
STL 不会加锁的。[/quote] deque不适合,因为我操作需要迭代器不失效,且经常中间插入元素 可是我试过用多线程同时删除每一个list对象,时间与单线程逐个删除差不多,不知是什么原因
赵4老师 2015-08-28
  • 打赏
  • 举报
回复
楼主该用数据库了。 <1000个元素,冒泡排序 <100000个元素,qsort函数 <10000000个元素,放数据库中,建索引,(B+树排序) ≥10000000个元素,没用到过。
dengqibin 2015-08-28
  • 打赏
  • 举报
回复
vector会比list更快,这个很不解啊,vector是数组类型的,删除了会进行拷贝移位什么的,list是链表试的,只用改指针,被删除的元素,两个容器都要调他的析构函数,应该是一样的,你确定是由于容器不一样产生的性能差别?
jiqiang01234 2015-08-28
  • 打赏
  • 举报
回复
可以用boost::pool当做,std::list的分配器模板参数来试试
paschen 版主 2015-08-28
  • 打赏
  • 举报
回复
今晚用boast库作为分配器(std::list<CString, boost::pool_allocator<CString> >),效率可以提高20%不到 可能之后也考虑使用数据库 谢谢大家给的意见,明天结帖!
paschen 版主 2015-08-28
  • 打赏
  • 举报
回复
引用 15 楼 zilaishuichina 的回复:
lz应该用池技术了 建一个对象池,预分配比如10000个 CString *pCStringArr = new CString[10000]; 建两个列表,分别保存使用中的对象下标,和未使用的对象下标 std::list<int> usedList; std::list<int> freeList;
用索引到是不错,只是插入数据有点不方便
paschen 版主 2015-08-28
  • 打赏
  • 举报
回复
引用 12 楼 ri_aje 的回复:
[quote=引用 9 楼 paschen 的回复:] [quote=引用 1 楼 ri_aje 的回复:] [quote=引用 楼主 paschen 的回复:] 我知道效率偏低的原因再于反复delete很多元素,如果用vector就会快很多 可是由于需要迭代器不失效以及频繁插入数据,所以不想换成其他容器
试过 std::deque 吗?
引用 楼主 paschen 的回复:
我试过在析构时创建多个线程,每个线程分别执行一个list对象的clear操作,可速度并没有改善,不知是否是由于STL对多线程加了锁
STL 不会加锁的。[/quote] deque不适合,因为我操作需要迭代器不失效,且经常中间插入元素 可是我试过用多线程同时删除每一个list对象,时间与单线程逐个删除差不多,不知是什么原因[/quote] 嗯,中间插入删除的话确实会导致 deque 迭代器失效。 c++ new/delete 是多线程安全的,估计是到这步最后都串行化了。这也是为什么 vector 会比 list 快很多的原因,因为 vector 只需要调用一次 delete,而 list 每删除一个节点就需要 delete 一下。 你可以先用 profiler 确认一下是不是这个问题,如果是的话,用 placement new 构造对象,销毁 list 的时候,先析构所有对象,然后再把 delete 的任务发到其他线程执行。[/quote] 好的,谢谢你建议
老王爱上猫 2015-08-28
  • 打赏
  • 举报
回复
这个问题我之前碰到过,但是没找到解决方法
fefe82 2015-08-28
  • 打赏
  • 举报
回复
debug? release?
未狂 2015-08-28
  • 打赏
  • 举报
回复
为什么我觉得对于删的操作,vector的效率应该比list差
707wk 2015-08-28
  • 打赏
  • 举报
回复
上数据库
zilaishuichina 2015-08-28
  • 打赏
  • 举报
回复
lz应该用池技术了 建一个对象池,预分配比如10000个 CString *pCStringArr = new CString[10000]; 建两个列表,分别保存使用中的对象下标,和未使用的对象下标 std::list<int> usedList; std::list<int> freeList;
GKatHere 2015-08-28
  • 打赏
  • 举报
回复
把几W个全放一个块中, 退出时不产生析构,直接DEL这个块
dustpg 2015-08-28
  • 打赏
  • 举报
回复
"在类对象析构时要析构好几分钟", 也太叼了, 用自带的剖析器看一下瓶颈所在。 lz再发早一点肯定有人发"无profiler不要谈效率!!尤其在这个云............."之类的东西. 遇到性能问题, 首先profiler, 查看瓶颈所在, 再看情况解决.
sdghchj 2015-08-28
  • 打赏
  • 举报
回复
试一下parallel_for
ri_aje 2015-08-28
  • 打赏
  • 举报
回复
引用 楼主 paschen 的回复:
我知道效率偏低的原因再于反复delete很多元素,如果用vector就会快很多 可是由于需要迭代器不失效以及频繁插入数据,所以不想换成其他容器
试过 std::deque 吗?
引用 楼主 paschen 的回复:
我试过在析构时创建多个线程,每个线程分别执行一个list对象的clear操作,可速度并没有改善,不知是否是由于STL对多线程加了锁
STL 不会加锁的。
ri_aje 2015-08-28
  • 打赏
  • 举报
回复
引用 9 楼 paschen 的回复:
[quote=引用 1 楼 ri_aje 的回复:] [quote=引用 楼主 paschen 的回复:] 我知道效率偏低的原因再于反复delete很多元素,如果用vector就会快很多 可是由于需要迭代器不失效以及频繁插入数据,所以不想换成其他容器
试过 std::deque 吗?
引用 楼主 paschen 的回复:
我试过在析构时创建多个线程,每个线程分别执行一个list对象的clear操作,可速度并没有改善,不知是否是由于STL对多线程加了锁
STL 不会加锁的。[/quote] deque不适合,因为我操作需要迭代器不失效,且经常中间插入元素 可是我试过用多线程同时删除每一个list对象,时间与单线程逐个删除差不多,不知是什么原因[/quote] 嗯,中间插入删除的话确实会导致 deque 迭代器失效。 c++ new/delete 是多线程安全的,估计是到这步最后都串行化了。这也是为什么 vector 会比 list 快很多的原因,因为 vector 只需要调用一次 delete,而 list 每删除一个节点就需要 delete 一下。 你可以先用 profiler 确认一下是不是这个问题,如果是的话,用 placement new 构造对象,销毁 list 的时候,先析构所有对象,然后再把 delete 的任务发到其他线程执行。

64,651

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧