我有一个我不断重用的STL容器(std :: list)。我的意思是我
使用callgrind进行性能分析时,我看到大量对new
(malloc
)和delete
(free
)的调用,这些调用非常昂贵。因此,我正在寻找一些方法来优先预分配相当多的元素。我还希望我的分配池继续增加,直到达到高水位线,并且分配池继续挂起到内存,直到容器本身被删除。
不幸的是标准分配器不断调整内存池的大小,所以我正在寻找一些能够完成上述操作的分配器,而不必自己编写。
这样的分配器是否存在,我在哪里可以找到这样的分配器?
我正在使用GCC和使用STLPort的Android工作。
编辑:展示位置new
没问题,我想要最小化的是堆行走,这是很昂贵的。我还希望我的所有对象尽可能地彼此接近,以最大限度地减少缓存未命中。
答案 0 :(得分:7)
听起来你可能只是使用了错误类型的容器:使用列表,每个元素占用一个单独的内存块,以允许单独的插入/删除 - 因此列表中的每个添加/删除都需要单独的{ {1}}。
如果您可以改用new()/delete()
,那么在添加项目之前,您可以std::vector
所需的尺寸。
同样,对于删除,通常最好不要单独删除项目。只需在容器上调用reserve
即可清空。它
修改:您现在已在评论中明确指出,“在处理期间删除元素”步骤是从列表中间删除元素,并且必须不会使迭代器无效,因此切换到矢量是不合适的。我现在就留下这个答案(为了评论帖子!)
答案 1 :(得分:6)
分配器boost::fast_pool_allocator
旨在与std::list
一起使用。
文档声称"如果您严重关注性能,请在处理boost::fast_pool_allocator
等容器时使用std::list
,并在处理容器时使用boost::pool_allocator
std::vector
"
请注意boost::fast_pool_allocator
是一个单例,默认情况下它永远不会释放已分配的内存。但是,它是使用boost::singleton_pool
实现的,您可以通过调用静态函数boost::singleton_pool::release_memory()
和boost::singleton_pool::purge_memory()
使其成为可用内存。
答案 2 :(得分:0)
您可以尝试使用http://goog-perftools.sourceforge.net/doc/tcmalloc.html对您的应用进行基准测试,我在某些项目中看到了一些不错的改进(虽然手头没有数字,抱歉)
编辑:似乎代码/下载已移至那里:http://code.google.com/p/gperftools/?redir=1
答案 3 :(得分:-1)
评论太短,所以我会发表我的想法作为答案。
IMO,new / delete只能在这种情况下来自两个地方。
我认为std::list<T>
是由某些节点实现的,因为通常的列表是出于各种原因。因此,每次插入和删除元素都必须导致节点的新/删除。此外,如果T
类型的对象在c / tor tor中有任何分配和解除分配,它们也会被调用。
您可以通过重复现有节点而不是删除它们来避免重新创建标准内容。如果您想将其压缩到c级,可以使用std::vector
和std::vector::reserve
或std::array
。
尽管如此,对于创建的每个对象,必须将其称为析构函数。我认为避免创建和破坏的唯一方法是在重复容器时使用T::operator=
,或者如果适合你的话,可以使用一些c ++ 13 move
。