C++ std::deque内存使用

C++ std::deque内存使用,c++,memory,stl,deque,C++,Memory,Stl,Deque,我已经实现了一个简单的统计引擎来返回滚动平均值和方差,使用deque来提供数据队列 deque由与值的滚动数相等的条目数构成 当一个新值到达时,最早的值从前面弹出,新值推到后面 我需要确保它不会在内存中增长,因为它将作为后台任务运行很长一段时间 deque是否在使用中的堆上进行分配? 是否有我可以用来确定其大小的标志 我在RHEL 5.3上使用G++4.1.2,本质上,任何动态大小的容器都从堆中分配内存。另一个问题提供了一个例子 但在您的特定情况下,队列的大小总是相同的。如果您遇到deque的问

我已经实现了一个简单的统计引擎来返回滚动平均值和方差,使用deque来提供数据队列

deque由与值的滚动数相等的条目数构成

当一个新值到达时,最早的值从前面弹出,新值推到后面

我需要确保它不会在内存中增长,因为它将作为后台任务运行很长一段时间

deque是否在使用中的堆上进行分配? 是否有我可以用来确定其大小的标志

我在RHEL 5.3上使用G++4.1.2,本质上,任何动态大小的容器都从堆中分配内存。另一个问题提供了一个例子

但在您的特定情况下,队列的大小总是相同的。如果您遇到deque的问题,那么在固定大小的数组上使用a实现一个简单的固定大小队列可能是有益的。这个实现应该从根本上具有更好的内存行为(因为它从不需要重新分配)。如果不分析数据,很难评估它的优势是否值得麻烦地实现。

本质上,任何动态大小的容器都会从堆中分配内存。另一个问题提供了一个例子


但在您的特定情况下,队列的大小总是相同的。如果您遇到deque的问题,那么在固定大小的数组上使用a实现一个简单的固定大小队列可能是有益的。这个实现应该从根本上具有更好的内存行为(因为它从不需要重新分配)。如果没有分析数据,很难评估它的优势是否值得麻烦地实现。

规范将实现细节留给供应商。但是,由于两端的插入都是有效的,因此它很可能是作为堆上的链接结构实现的。这就是说,当您从堆中弹出某个内容时,它应该被解构,因此您的总内存使用量不应该上升。

规范将实现细节留给供应商。但是,由于两端的插入都是有效的,因此它很可能是作为堆上的链接结构实现的。这就是说,当你从堆中弹出一些东西时,它应该被解构,这样你的总内存使用率就不会上升。

作为一个提示,如果你不需要跟踪这些值,有一个非常轻量级的伟大算法(我甚至在8位微秒上使用它),而且是准确的

 class RunningStat
{
public:
    RunningStat() : m_n(0) {}

    void Clear()
    {
        m_n = 0;
    }

    void Push(double x)
    {
        m_n++;

        // See Knuth TAOCP vol 2, 3rd edition, page 232
        if (m_n == 1)
        {
            m_oldM = m_newM = x;
            m_oldS = 0.0;
        }
        else
        {
            m_newM = m_oldM + (x - m_oldM)/m_n;
            m_newS = m_oldS + (x - m_oldM)*(x - m_newM);

            // set up for next iteration
            m_oldM = m_newM; 
            m_oldS = m_newS;
        }
    }

    int NumDataValues() const
    {
        return m_n;
    }

    double Mean() const
    {
        return (m_n > 0) ? m_newM : 0.0;
    }

    double Variance() const
    {
        return ( (m_n > 1) ? m_newS/(m_n - 1) : 0.0 );
    }

    double StandardDeviation() const
    {
        return sqrt( Variance() );
    }

private:
    int m_n;
    double m_oldM, m_newM, m_oldS, m_newS;
};
该算法由B.p.Welford创建,并在Donald Knuth的《计算机编程艺术》(Art of Computer Programming)第2卷第232页第3版中介绍


作为提示,如果您不需要跟踪数值,有一个非常轻量级的伟大算法(我甚至在8位微秒上使用它),而且非常准确

 class RunningStat
{
public:
    RunningStat() : m_n(0) {}

    void Clear()
    {
        m_n = 0;
    }

    void Push(double x)
    {
        m_n++;

        // See Knuth TAOCP vol 2, 3rd edition, page 232
        if (m_n == 1)
        {
            m_oldM = m_newM = x;
            m_oldS = 0.0;
        }
        else
        {
            m_newM = m_oldM + (x - m_oldM)/m_n;
            m_newS = m_oldS + (x - m_oldM)*(x - m_newM);

            // set up for next iteration
            m_oldM = m_newM; 
            m_oldS = m_newS;
        }
    }

    int NumDataValues() const
    {
        return m_n;
    }

    double Mean() const
    {
        return (m_n > 0) ? m_newM : 0.0;
    }

    double Variance() const
    {
        return ( (m_n > 1) ? m_newS/(m_n - 1) : 0.0 );
    }

    double StandardDeviation() const
    {
        return sqrt( Variance() );
    }

private:
    int m_n;
    double m_oldM, m_newM, m_oldS, m_newS;
};
该算法由B.p.Welford创建,并在Donald Knuth的《计算机编程艺术》(Art of Computer Programming)第2卷第232页第3版中介绍


是的,在这种情况下,缓冲区将非常简单。只需跟踪要插入的下一个索引。一旦它结束,你将覆盖旧的值,给你你想要的行为。顺便说一句:boost有一个循环缓冲区:是的,在这种情况下,缓冲区将非常简单。只需跟踪要插入的下一个索引。一旦它结束,你将覆盖旧的值,给你你想要的行为。顺便说一句:boost有一个循环缓冲区:一个“链接结构”不会切断它,因为deque保证O(1)索引访问。一些细节留给供应商,但是基于向量的页面实现是非常必要的。一个“链接结构”并不能解决它,因为deque保证了O(1)索引访问。一些细节留给供应商,但基于向量的页面实现是非常必要的。我一直在研究是否可以将其调整为使用固定大小的差异窗口。我正试图利用最古老的术语,介绍新的术语。我的初步测试表明它会起作用。有人知道这是不是一条死胡同吗?使用这种方法,我需要将数据保存在一个循环缓冲区中,但简单的增量和将避免进行大量的平均。我一直在研究这种方法是否适用于使用固定大小的方差窗口。我正试图利用最古老的术语,介绍新的术语。我的初步测试表明它会起作用。有人知道这是不是一条死胡同吗?使用这种方法,我需要将数据保存在一个循环缓冲区中,但是一个简单的增量和将避免进行大量的平均。