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

C++ std::deque内存使用-Visual C++;,以及与他人的比较,c++,memory-management,deque,C++,Memory Management,Deque,后续行动 VisualC++根据容器元素类型管理代码> DeQue/Cuth.Bug:使用: #define _DEQUESIZ (sizeof (value_type) <= 1 ? 16 \ : sizeof (value_type) <= 2 ? 8 \ : sizeof (value_type) <= 4 ? 4 \ : sizeof (value_type) <= 8 ? 2 \ : 1) /* elements pe

后续行动

VisualC++根据容器元素类型管理<>代码> DeQue/Cuth.Bug:使用:

#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) */
gcc已经定义了

return __size < 512 ? size_t(512 / __size) : size_t(1);
Dinkumware(MS)实现希望将deque一次增加16字节。这可能只是一个非常古老的实现(像第一个实现一样?),它针对内存非常少的平台进行了调整(按照今天的标准),以防止过度分配和耗尽内存(像
std::vector
就可以了)

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

互联网上似乎很少有证据表明人们会遇到这种效率低下的情况,这让我感到惊讶。我认为像队列这样的基本数据结构(标准库)在野外非常普遍,在性能/时间/空间关键型应用程序中也会如此。但我们现在看到了

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

…致:

因此,似乎有某种机制可以通过专门化覆盖块大小,而…的定义如下所示:

// 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;
}
//为需要更多空间的容器返回建议的新容量
模板
内联\u RWSTD\u容器\u尺寸\u类型
__rw\U新容量(RWSTD\U容器大小\U类型大小,const\U容器*)
{
typedef_RWSTD_CONTAINER_SIZE_TYPE_RWSizeT;
常数比=(新容量比>10)*
+((((uuu大小和0x3ff)*\uu比率)>>10);
返回(\uuuu大小+=\urwstd\u最小\uu新容量)>\uu上限?\uuuu大小:\uuuu上限;
}
所以我想说,嗯,很复杂


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

你不能编写一个自定义分配器来分配更大的块吗?@Space_C0wb0y-是的,但我认为这是不可取的(Meyers等人).@Space_C0wb0y-自定义分配器可能会有所帮助,但不能完全解决此问题。不过,每个deque块中都有deque的变量,因此无论如何都会有开销。@valdo-不仅是每个块的信息,而且是每个块的堆管理器信息。对于
deque
,开销几乎与成员存储相同。他们为什么要这样做呢史蒂夫:“他们为什么要这样做?”-我能想到的第一个答案是,MS/Dinkumware没有在这方面真正研究优化
deque
。从GCC source@AProgrammer引号中的评论来看,GNU也没有,它只是拥有一个更适合大型
deque
的常量。创建10个deque,每个deque包含10个字符,然后突然看到Alc++是一个天才,GCC是一个有5000%开销的坏人。大概可以实现一个代码< > DeQu/C++ >从小块开始,然后增加块大小。你能把这个扩展一点吗?就是:什么是代码>大小?<代码>这里?马蒂厄:它实际上是一个内联函数的参数,<代码>f_size,但无论在哪里调用它,参数都是
sizeof(_Tp)
,乍一看似乎
_Tp
总是deque的值类型。@Steve:谢谢,这意味着使用GCC,块大小约为512字节(如果
sizeof(_Tp)<512
,则最多为512字节,否则为对象大小)。有趣的是,这并不是随着缓存变大而演变的。当然,这个系统存在更多的潜在浪费(即如果您的数据中只有一个
char
,那么您仍然有一个
512
字节块…)一个有趣的猜想。at的纯软件代码实际上使用了这个,参考了VC++5.0,它是古老的。#define"DEQUESIZ(4096\u DEQUESIZ更小了!
::: <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);
}
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);
}
// 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;
}