跟进What the heque is going on with the memory overhead of std::deque?
Visual C ++使用以下方法根据容器元素类型管理deque
块:
#define _DEQUESIZ (sizeof (value_type) <= 1 ? 16 \
: sizeof (value_type) <= 2 ? 8 \
: sizeof (value_type) <= 4 ? 4 \
: sizeof (value_type) <= 8 ? 2 \
: 1) /* elements per block (a power of 2) */
这会导致小元素的内存占用非常大。通过将第一行中的16更改为128,我可以大幅减少大deque<char>
所需的占用空间。 Process Explorer Private Bytes从181MB下降 - &gt; 100米push_back(const char& mychar)
电话后,113MB。
#define
? deque
块
浆纱? push_back
来电
deque<char>
? <deque>
代码?答案 0 :(得分:5)
gcc已经
return __size < 512 ? size_t(512 / __size) : size_t(1);
带评论
/* The '512' is
* tunable (and no other code needs to change), but no investigation has
* been done since inheriting the SGI code.
*/
答案 1 :(得分:3)
Dinkumware(MS)实现希望一次增加16个字节的双端队列。难道这只是一个非常古老的实现(就像有史以来的第一个吗?),它被调整为具有极少内存的平台(按照今天的标准),以防止过度分配和耗尽内存(就像std::vector
一样) ?
我必须在我正在处理的应用程序中实现自己的队列,因为std::queue
(使用std::deque
)的2.5倍内存占用是不可接受的。
似乎很少有关于互联网的证据表明人们已经遇到这种低效率,这对我来说是令人惊讶的。我认为这样一个基本的数据结构作为一个队列(标准库,不能少)在野外会非常普遍,并且会在性能/时间/空间关键应用程序中。但我们在这里。
要回答最后一个问题,C ++标准没有定义用于修改块大小的接口。我很确定它不会强制要求任何实现,只是两端插入/删除的复杂性要求。
答案 2 :(得分:2)
::: <stl/_alloc.h>
...
enum { _MAX_BYTES = 32 * sizeof(void*) };
...
::: <deque>
...
static size_t _S_buffer_size()
{
const size_t blocksize = _MAX_BYTES;
return (sizeof(_Tp) < blocksize ? (blocksize / sizeof(_Tp)) : 1);
}
这意味着32位的块大小为32 x 4 = 128字节,64位的块大小为32 x 8 = 256字节。
我的想法:从大小开销的POV来看,我认为任何实现使用可变长度块都是有意义的,但我认为这对于{{1的恒定时间随机访问要求来说是非常困难的}}
至于问题
STL是否允许在编译时覆盖此块大小而不修改代码?
这里也不可能。
(似乎是Rogue Wave STL版本)显然使用:
deque
因此似乎有某种机制通过专门化来覆盖块大小,而......的定义如下所示:
static size_type _C_bufsize () {
// deque only uses __rw_new_capacity to retrieve the minimum
// allocation amount; this may be specialized to provide a
// customized minimum amount
typedef deque<_TypeT, _Allocator> _RWDeque;
return _RWSTD_NEW_CAPACITY (_RWDeque, (const _RWDeque*)0, 0);
}
所以我会说,这很复杂。
(如果有人想要进一步解决这个问题,请随时直接编辑我的答案或只是发表评论。)