我已經實現了一個簡單的統計引擎來使用deque返回滾動均值和方差來提供數據隊列。std :: deque內存使用
該deque構造的條目數量等於滾動數值。
當新值到達時,最早的值被彈出前面,新的值被推到後面。
我需要確定這不會在內存中增長,因爲它預計會長時間作爲後臺任務運行。
Deque是否在堆中分配使用? 有沒有可以用來修復尺寸的標誌?
我上RHEL 5.3
我已經實現了一個簡單的統計引擎來使用deque返回滾動均值和方差來提供數據隊列。std :: deque內存使用
該deque構造的條目數量等於滾動數值。
當新值到達時,最早的值被彈出前面,新的值被推到後面。
我需要確定這不會在內存中增長,因爲它預計會長時間作爲後臺任務運行。
Deque是否在堆中分配使用? 有沒有可以用來修復尺寸的標誌?
我上RHEL 5.3
基本上採用G ++ 4.1.2,任何動態大小的容器中從堆中分配內存。另一個問題提供了一個overview over the implementation of the deque。
但在您的特定情況下,隊列始終具有相同的大小。如果遇到問題,可以使用固定大小的陣列上的circular buffer實現簡單的固定大小隊列。這個實現應該具有更好的內存行爲(因爲它永遠不需要重新分配)。如果沒有分析數據,它的優勢是否值得實施的麻煩很難評估。
該規範將實施細節留給供應商。但是,由於兩端的插入是有效的,所以它很可能作爲堆上的鏈接結構來實現。這就是說,當你從堆中彈出某些東西時,它應該被解構,所以你的總內存使用量不應該增加。
「鏈接結構」不會削減它,因爲deque保證O (1)索引訪問。一些細節留給供應商,但基於矢量的頁面實現是非常必要的。 –
就像一個提示,如果你不需要跟蹤值,那麼這個非常輕量級的算法是非常重要的(我甚至在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版的高德納的藝術呈現。
我一直在尋找這是否可以適應使用固定大小的窗口差異。我正在嘗試採用最古老的術語,並引入新的術語。我最初的測試表明它會起作用。有誰知道這是否是死路一條?使用這個我需要將數據保存在一個循環緩衝區中,但是一個簡單的增量和將避免進行大量的平均。 – DanS
是啊,在這種情況下,緩衝區將是非常簡單的。只需跟蹤下一個要插入的索引。一旦它繞過,你會覆蓋舊的價值觀,給你準確的行爲,你正在尋找。 – jpm
順便提一下:boost有一個循環緩衝區:http://www.boost.org/doc/libs/1_46_1/libs/circular_buffer/doc/circular_buffer.html – stefaanv