5

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

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

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

不幸的是,标准分配器不断调整内存池的大小,所以我正在寻找一些可以完成上述任务的分配器,而无需我自己编写。

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

我在使用 GCC 的 Linux 和使用 STLPort 的 Android 上工作。

编辑:放置new还可以,我想最小化的是堆走,这很昂贵。我还希望我的所有对象都尽可能靠近,以尽量减少缓存未命中。

4

4 回答 4

7

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

如果您可以使用 astd::vector代替,那么您可以reserve在添加项目之前设置所需的大小。

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


编辑:您现在已经在评论中明确表示,您的“在处理期间删除元素”步骤是从列表中间删除元素,并且不能使迭代器无效,因此切换到向量是不合适的。我暂时留下这个答案(为了评论线程!)

于 2013-06-21T10:33:05.217 回答
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().

于 2013-06-21T11:11:55.753 回答
0

您可以尝试使用http://goog-perftools.sourceforge.net/doc/tcmalloc.html对您的应用程序进行基准测试,我在一些项目中看到了一些很好的改进(虽然手头没有数字,抱歉)

编辑:似乎代码/下载已移至那里:http ://code.google.com/p/gperftools/?redir=1

于 2013-06-21T10:42:23.357 回答
-1

评论太短了,所以我将发表我的想法作为答案。

IMO,在这种情况下,新/删除只能来自两个地方。

由于各种原因,我相信std::list<T>是用某种节点来实现的,就像通常的列表一样。因此,每次插入和删除元素都必须导致新/删除节点。此外,如果类型的对象T在 c'tor/d'tor 中有任何分配和释放,它们也会被调用。

您可以通过重复现有节点而不是删除它们来避免重新创建标准内容。您可以使用std::vectorandstd::vector::reserve或者std::array如果您想将其压缩到 c 级别。

尽管如此,对于创建的每个对象,都必须调用一个析构函数。我看到避免创建和破坏的唯一方法是T::operator=在重复容器时使用,或者move如果它适合您的情况,可能是一些 c++13 的东西。

于 2013-06-21T11:07:10.150 回答