std :: deque内存使用 - Visual C ++,以及与其他人的比较

时间:2010-11-04 14:35:50

标签: c++ memory-management deque

跟进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块 浆纱?
  • 他们的足迹是什么? (32位操作)简单 测试100米push_back来电 deque<char>
  • STL是否允许 覆盖此块大小 编译时,无需修改 <deque>代码?

3 个答案:

答案 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)

STLPort

... seemsuse

::: <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是否允许在编译时覆盖此块大小而不修改代码?

这里也不可能。

Apache

(似乎是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);
}

所以我会说,这很复杂。

(如果有人想要进一步解决这个问题,请随时直接编辑我的答案或只是发表评论。)