带堆栈和动态分配的容器

发布于 2024-10-07 09:55:31 字数 814 浏览 0 评论 0原文

是否有容器对少量元素使用本地缓冲区,并且仅当元素数量超过一定限制时才使用堆分配?与大多数 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 在第一次传递期间增长,项目数量不可预测但仍然很低

Is there a container that uses a local buffer for a small number of elements, and uses a heap allocation only when the number of elements exceeds a certain limit? Similar to what most std::string implementations do.


Background

The container is used in the following (simplified) context:

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)
{
  // ...
}

This code part has high call frequency, but tagging an item is rather rare, number of items in someContainer is usually low but unbound. I can't use a preallocated "more global" buffer easily. The goal is to avoid the frequent allocation.


Call Frequency

  • Common: no item becomes tagged. std::vector is fine
  • Common: only one of a few items become tagged. causes high frequency allocation I want to avoid
  • Very rare, but must be supported: someList grows during first pass, number of items not predictable but still low

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

云巢 2024-10-14 09:55:31

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

有关创建自定义分配器的信息,您应该阅读这篇文章。

There is no standard container which guarantees this sort of behavior. However, if you're up to it, you can create a custom STL-compatible allocator class that draws from a small stack buffer for small allocations, and only performs a heap allocation when the requested allocation size exceeds the size of the stack buffer. You can plug-in your custom allocator class as the second template parameter for std::vector<T, Alloc>.

For information on creating a custom allocator, you should read this article.

画中仙 2024-10-14 09:55:31

尽管不能保证这一点,但大多数 std::string 将实现小字符串优化,这就是(对于 VC++10,最多 8 或 16 个字符)存储)

我还没有看到向量这样做,并且一直想知道为什么,但即将推出的C++标准将通过std::aligned_storagealignof来促进这一点>。这样我们就能够正确对齐原始内存并使用一些默认数量的“堆栈”内存构建容器。

Though this is not guaranteed, most std::string will implement the Small String Optimization, which is just that (with VC++10 up to 8 or 16 characters are thusly stored)

I have not seen vectors do it, and always wondered why, but the upcoming C++ standard will facilitate this with std::aligned_storage and alignof. This way we'll be able to get properly aligned raw memory and build containers with some default number of "stack" memory.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文