带堆栈和动态分配的容器
是否有容器对少量元素使用本地缓冲区,并且仅当元素数量超过一定限制时才使用堆分配?与大多数 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
没有标准容器可以保证这种行为。但是,如果您愿意,可以创建一个自定义的 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.
尽管不能保证这一点,但大多数
std::string
将实现小字符串优化
,这就是(对于 VC++10,最多 8 或 16 个字符)存储)我还没有看到
向量
这样做,并且一直想知道为什么,但即将推出的C++标准将通过std::aligned_storage
和alignof
来促进这一点>。这样我们就能够正确对齐原始内存并使用一些默认数量的“堆栈”内存构建容器。Though this is not guaranteed, most
std::string
will implement theSmall 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 withstd::aligned_storage
andalignof
. This way we'll be able to get properly aligned raw memory and build containers with some default number of "stack" memory.