具有堆栈和动态分配的容器

时间:2010-12-10 07:09:24

标签: c++ optimization stl containers

是否有一个容器为少量元素使用本地缓冲区,并且仅在元素数超过某个限制时才使用堆分配?与大多数std::string实现类似。


背景

容器用于以下(简化)上下文:

Foo foo;                     // some data
vector<HandlerPtr> tagged;   // receives "tagged" items

// first pass: over all items in someList
for each(HandlerPtr h in someList)
{
  h->HandleFoo(foo);         // foo may become tagged or untagged here
  if (foo.Tagged())
    tagged.push_back(h);
}
for(auto itr=tagged.rbegin(); itr!=tagged.end(); ++itr)
{
  // ...
}

此代码部分具有较高的通话频率,但标记项目的情况相当罕见,someContainer中的项目数通常较低但未绑定。我不能轻易使用预分配的“更全局”缓冲区。目标是避免频繁分配。


通话频率

  • 常见:没有项目被标记。 std :: vector很好
  • 常见:只有少数项目中的一个被标记。导致高频率分配我想避免
  • 非常罕见,但必须得到支持:someList在第一次通过期间增长,项目数量不可预测但仍然很低

2 个答案:

答案 0 :(得分:3)

没有标准容器可以保证这种行为。但是,如果您已了解它,则可以创建一个自定义STL兼容的分配器类,该类从小堆栈缓冲区中进行小分配,并且仅在请求的分配大小超过堆栈缓冲区大小时执行堆分配。您可以将自定义分配器类作为std::vector<T, Alloc>的第二个模板参数插​​入。

有关创建自定义分配器的信息,请阅读this article

答案 1 :(得分:0)

虽然无法保证,但大多数std::string会实现Small String Optimization,就是这样(因此VC ++ 10最多可存储8个或16个字符)

我还没有看到vectors这样做,并且总是想知道为什么,但即将推出的C ++标准将通过std::aligned_storagealignof来实现这一目标。通过这种方式,我们将能够正确对齐原始内存并使用默认数量的“堆栈”内存构建容器。