2011-06-28 52 views
1

我已經實現了一個簡單的統計引擎來使用deque返回滾動均值和方差來提供數據隊列。std :: deque內存使用

該deque構造的條目數量等於滾動數值。

當新值到達時,最早的值被彈出前面,新的值被推到後面。

我需要確定這不會在內存中增長,因爲它預計會長時間作爲後臺任務運行。

Deque是否在堆中分配使用? 有沒有可以用來修復尺寸的標誌?

我上RHEL 5.3

回答

8

基本上採用G ++ 4.1.2,任何動態大小的容器中從堆中分配內存。另一個問題提供了一個overview over the implementation of the deque

但在您的特定情況下,隊列始終具有相同的大小。如果遇到問題,可以使用固定大小的陣列上的circular buffer實現簡單的固定大小隊列。這個實現應該具有更好的內存行爲(因爲它永遠不需要重新分配)。如果沒有分析數據,它的優勢是否值得實施的麻煩很難評估。

+0

是啊,在這種情況下,緩衝區將是非常簡單的。只需跟蹤下一個要插入的索引。一旦它繞過,你會覆蓋舊的價值觀,給你準確的行爲,你正在尋找。 – jpm

+6

順便提一下:boost有一個循環緩衝區:http://www.boost.org/doc/libs/1_46_1/libs/circular_buffer/doc/circular_buffer.html – stefaanv

0

該規範將實施細節留給供應商。但是,由於兩端的插入是有效的,所以它很可能作爲堆上的鏈接結構來實現。這就是說,當你從堆中彈出某些東西時,它應該被解構,所以你的總內存使用量不應該增加。

+0

「鏈接結構」不會削減它,因爲deque保證O (1)索引訪問。一些細節留給供應商,但基於矢量的頁面實現是非常必要的。 –

2

就像一個提示,如果你不需要跟蹤值,那麼這個非常輕量級的算法是非常重要的(我甚至在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.維爾福德創建,並在計算機程序設計,第2卷,第232頁,第3版的高德納的藝術呈現。

http://www.johndcook.com/standard_deviation.html

+0

我一直在尋找這是否可以適應使用固定大小的窗口差異。我正在嘗試採用最古老的術語,並引入新的術語。我最初的測試表明它會起作用。有誰知道這是否是死路一條?使用這個我需要將數據保存在一個循環緩衝區中,但是一個簡單的增量和將避免進行大量的平均。 – DanS

相關問題