首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >std::deque内存使用情况-可视化C++,以及与其他内存使用情况的比较

std::deque内存使用情况-可视化C++,以及与其他内存使用情况的比较
EN

Stack Overflow用户
提问于 2010-11-04 22:35:50
回答 3查看 2.9K关注 0票数 19

跟进What the heque is going on with the memory overhead of std::deque?

Visual C++使用以下命令根据容器元素类型管理deque块:

代码语言:javascript
复制
#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>所需的内存占用。进程浏览器专用字节在100m push_back(const char& mychar)调用后从181MB -> 113MB下降)。

  • 谁能证明该#define中的值是正确的?
  • 其他编译器如何处理deque块大小?
  • 对于对<代码>D14的100m push_back调用的简单测试,它们的占用空间(32位操作)是多少?<代码>H215<代码>H116是否允许在编译时覆盖此块大小,而无需修改<代码>D17代码?<代码>H218<代码>F219
EN

回答 3

Stack Overflow用户

发布于 2010-11-04 23:34:31

gcc有

代码语言:javascript
复制
return __size < 512 ? size_t(512 / __size) : size_t(1);

带注释

代码语言:javascript
复制
/*  The '512' is
 *  tunable (and no other code needs to change), but no investigation has
 *  been done since inheriting the SGI code.
 */
票数 5
EN

Stack Overflow用户

发布于 2010-11-05 01:00:54

Dinkumware (MS)实现希望一次将双队列增加16字节。这会不会只是一个非常老的实现(就像第一个实现一样)?这是为内存非常少的平台(按照今天的标准)进行了调整,以防止过度分配和耗尽内存(就像std::vector一样)?

我不得不在我正在开发的应用程序中实现我自己的队列,因为std::queue (它使用std::deque)的2.5倍内存占用是不可接受的。

在互联网上似乎很少有证据表明人们遇到了这种低效,这让我感到惊讶。我认为像队列(标准库)这样的基本数据结构在自然界中会非常普遍,并且会出现在性能/时间/空间关键的应用程序中。但我们还是来了。

为了回答最后一个问题,C++标准没有定义用于修改块大小的接口。我很确定它并没有强制要求任何实现,只是对两端的插入/删除的复杂性要求。

票数 3
EN

Stack Overflow用户

发布于 2011-11-24 21:38:02

STLPort

...从seemsuse

代码语言:javascript
复制
::: <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字节的块大小。

我的想法是:从大小开销的观点来看,我猜对于任何实现来说,操作可变长度的块都是有意义的,但我认为在deque的恒定时间随机访问要求下,这将是非常困难的。

至于问题

STL是否允许在编译时覆盖此块大小,而无需修改代码?

在这里也不可能。

Apache

(似乎是Rogue Wave STL版本)显然使用:

代码语言:javascript
复制
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);
}

因此,似乎有一些机制可以通过专门化和定义来覆盖块大小。看起来像这样:

代码语言:javascript
复制
// returns a suggested new capacity for a container needing more space
template <class _Container>
inline _RWSTD_CONTAINER_SIZE_TYPE
__rw_new_capacity (_RWSTD_CONTAINER_SIZE_TYPE __size, const _Container*)
{
    typedef _RWSTD_CONTAINER_SIZE_TYPE _RWSizeT;

    const _RWSizeT __ratio = _RWSizeT (  (_RWSTD_NEW_CAPACITY_RATIO << 10)
                                       / _RWSTD_RATIO_DIVIDER);

    const _RWSizeT __cap =   (__size >> 10) * __ratio
                           + (((__size & 0x3ff) * __ratio) >> 10);

    return (__size += _RWSTD_MINIMUM_NEW_CAPACITY) > __cap ? __size : __cap;
}

所以我会说,嗯,很复杂。

(如果有人想进一步弄清楚这一点,请直接编辑我的答案或留下评论。)

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4097729

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档