sbi*_*sbi 8 c++ string allocator stack-allocation
在大约十年前的一个项目中,我们发现std::vector
动态分配导致了严重的性能损失.在这种情况下,它分配了许多小向量,因此快速解决方案是编写一个类似于向量的类,包装在基于堆栈的预分配char
数组中,用作其容量的原始存储.结果是static_vector<typename T, std::size_t Max>
.如果您了解一些基础知识,这样的事情很容易写,你可以在网上找到很多这样的野兽.事实上,现在也有一个提升.
现在在嵌入式平台上工作,我们碰巧需要一个static_basic_string
.这将是一个字符串,它预先在堆栈上分配固定的最大内存量,并将其用作容量.
起初我认为这应该相当容易(static_vector
毕竟它可以基于现有的),但再看看std::basic_string
界面我不再那么肯定了.它比std::vector
界面更复杂.特别是实现find()
功能系列std::basic_string
不仅仅是一项繁琐的工作.
这让我再次思考.毕竟,这就是创建分配器的原因:基于new
和delete
使用其他方法替换分配.但是,要说分配器接口不实用将是轻描淡写.有一些文章在那里解释它,但有一个原因,我在过去的15年中看到这么少的本土分配器.
所以这是我的问题:
如果你必须实现一个basic_string
相似的,你会怎么做?
static_basic_string
?std::basic_string
?与往常一样,对我们来说存在相当重要的限制:在嵌入式平台上,我们与GCC 4.1.2绑定,因此我们只能使用C++ 03,TR1和boost 1.52.
第一个问题是:你使用了多少额外的接口?大多数std::string
附加接口都可以使用<algorithm>
(例如
std::find
,std::find_if
和std::search
)中的函数轻松实现,并且在很多情况下,其中有很大一部分无论如何都不会被使用。只需根据需要实施即可。
我认为你不能使用自定义分配器来完成这项工作。获得“堆栈上”内存的唯一方法是将其声明为自定义分配器的成员,这在复制它们时会产生各种问题。分配器必须是可复制的,并且副本必须是幂等的。
也许你可以在网上找到一个免费的实现,
std::string
它使用小字符串实现;然后修改它,使截止大小(超过它使用动态分配)大于您实际使用的任何字符串。(标准库有多种开源实现;与 g++ 一起提供的实现仍然使用 COW,但我怀疑其他大多数都使用 SSO。)