防止STL容器中的内存释放

dor*_*ron 5 c++ memory-management stl

我有一个我不断重用的STL容器(std :: list).我的意思是我

  1. 将许多元素推入容器中
  2. 在处理过程中删除元素
  3. 清理容器
  4. 冲洗并重复多次

使用callgrind进行性能分析时,我看到大量的new(malloc)和delete(free)调用非常昂贵.因此,我正在寻找一些方法来优先预分配相当多的元素.我还希望我的分配池继续增加,直到达到高水位线,并且分配池继续挂起到内存,直到容器本身被删除.

不幸的是,标准分配器不断调整内存池的大小,所以我正在寻找一些能够完成上述操作的分配器,而不必自己编写.

这样的分配器是否存在,我在哪里可以找到这样的分配器?

我正在使用GCC和使用STLPort的Android工作.

编辑:放置new是好的,我想要最小化的是堆行走,这是昂贵的.我也希望我的所有对象尽可能地彼此接近,以最大限度地减少缓存未命中.

Rod*_*ddy 7

听起来你可能只是使用了错误类型的容器:使用列表,每个元素占用一个单独的内存块,以允许单独的插入/删除 - 因此列表中的每个添加/删除都需要单独的new()/delete().

如果您可以使用std::vector替代,那么您可以reserve在添加项目之前获得所需的大小.

同样要删除,通常最好不要单独删除项目.只需调用clear()容器即可清空.它.


编辑:您现在已经在评论中明确指出," 在处理过程中删除元素"步骤是从列表中间删除元素,并且不能使迭代器无效,因此切换到向量是不合适的.我现在就留下这个答案(为了评论帖子!)

  • @doron然后这对于`std :: list`确实是一个完美的(如果不是唯一合理的)用例,你应该在你对这个答案的第一个评论中提到而不是性能论证,因为前者是一个很难的理由为什么你不能使用`std :: vector`而不是讨论伪理由. (3认同)
  • @doron包含内容的顺序是什么?如果没有,你可以简单地用最后一个元素和`pop_back()`交换待删除.没有洗牌. (2认同)
  • @doron尽管如此,内存改组可能比你想象的还要少.看看Bjarne Stroustrup解释向量与列表的好处http://channel9.msdn.com/Events/GoingNative/GoingNative-2012/Keynote-Bjarne-Stroustrup-Cpp11-Style(从44:40开始)简而言之,即使你删除很多并插入很多,列表中线性搜索的时间完全占据了处理时间,因为对象分散在内存中并且会损害cpu缓存. (2认同)
  • @doron*"除非我想删除列表中间的元素,而没有std :: vector将需要的内存随机播放"* - 你已经使用了一个分析器,所以只是冒险进行测试并比较矢量的速度列出疯狂的分配疯狂.结果可能会令人惊讶(并且可能会破坏您对big-O表示法的看法;)). (2认同)

Joh*_*åde 6

分配器boost::fast_pool_allocator设计用于std::list.

该文件声称"如果您严重关注性能,请boost::fast_pool_allocator在处理容器时使用,例如在处理容器时std::list使用."boost::pool_allocatorstd::vector

请注意,这boost::fast_pool_allocator是一个单例,默认情况下它永远不会释放已分配的内存.但是,它是使用实现的boost::singleton_pool,您可以通过调用静态函数boost::singleton_pool::release_memory()和它来使其空闲内存boost::singleton_pool::purge_memory().