単純なバッファ クラスを書いているとします。このバッファは、オブジェクトの標準 C 配列の単純なラッパーとして機能します。また、単純な配列を入力として受け取る既存の関数を操作するには、下位互換性がある必要があります。
ここでの目標は、このバッファーを速度とメモリ使用量の両方で効率的にすることです。スタック割り当ては常にヒープよりも高速であるため、スタック上のすべてのものを特定のしきい値に割り当て、それが大きくなった場合はヒープに再割り当てしたいと考えています。これを効率的に行うにはどうすればよいでしょうか。
私が調査したところ、明らかに std::string は同様のことを行います。方法がわかりません。私が持っていた最も近い解決策は、(擬似コード、コンパイルされていない)の行に沿ったものでした:
template <typename T, int MinSize>
class Buffer
{
public:
void Push(const T& t)
{
++_size;
if (_size > MinSize && _heap == NULL)
{
// allocate _heap and copy contents from stack
// _stack is unused and wasted memory
}
else if (_heap != NULL)
{
// we already allocated _heap, append to it, re-allocate if needed
}
else
{
// still got room on stack, append to _stack
}
}
void Pop()
{
--_size;
if (_size <= MinSize && _heap != NULL)
{
// no need for _heap anymore
// copy values to _stack, de-allocate _heap
}
else if (_heap != NULL)
{
// pop from heap
}
else
{
// pop from stack
}
}
private:
T _stack[MinSize];
T* _heap;
int _size;
};
ご覧のとおり_stack
、バッファが を超えて大きくなると、単にスペースが無駄になりますMinSize
。また、Buffer が十分に大きい場合、push と pop は特にコストがかかる可能性があります。別の解決策は、最初のいくつかの要素を常にスタックに保持し、オーバーフローをヒープに配置することでした。しかし、それは Buffer を単純な配列に「変換」できなかったことを意味します。
より良い解決策はありますか?これが std::string で行われる場合、誰かがその方法を指摘したり、リソースを提供したりできますか?