2013-07-07 84 views
0

。結構的內容隨時間變化,特別是每個嵌套矢量的長度是隨機的並隨時間變化。順序很重要,如果它是空的,我不能忽略嵌套向量。我知道嵌套矢量(比如m)和外部矢量(比如n)的最大容量。初始化我使用</p> <pre><code>vector<vector<size_t>> Ar; </code></pre> <p>結構矢量矢量

我有一些難以獲得初始化權。如果我使用

Ar(n); 

是沒有問題的,但我最終得到一個內存碎片,因爲分配不知道嵌套向量的大小。如果可能,我想避免這種情況,因爲我不知道隨着我嘗試處理的數據量的增加會產生什麼樣的影響。我試圖通過預先固定嵌套向量的長度來獲得緊湊的表示形式來解決碎片問題,但是我在執行此操作時遇到了問題。我用

Ar(n,vector<size_t>(m)); 

但這是超級慢和大量的內存浪費,因爲大多數條目將不會被使用。

我已經成功地與一個

vector<list<size_t> > Ar(n); 

實現了這個無痛苦碎片,但它的運行速度比使用嵌套向量慢得多。像Boost :: multi_array這樣的固定表示會佔用太多空間,出於與上面第二次初始化相同的原因,並且實現起來會更加困難,因爲我需要跟蹤有用條目的停止位置。

有什麼建議嗎?提前致謝。

+1

爲什麼您的原始設計的「內存碎片」是一個問題?你是否測量過它並確定它確實是一個瓶頸? –

+0

我測量了虛擬內存使用情況。這是否是錯誤的?我應該使用另一種工具嗎? – Plamen

+0

我只是沒有看到你最初的做法特別錯誤。如果你有一組不同大小的集合,那麼矢量矢量似乎是合理的。如果你正在縮小容器並且擔心內存,你可以使用交換技巧,但是否則你已經在每個內部容器中獲得了良好的內存局部性...... –

回答

1

在使用典型用例分析代碼之前,您不知道內存碎片是否有問題。 除非mn之前很小,否則我認爲它不會成爲瓶頸,因爲你仍然主要是順序存儲器訪問。

如果您想避免它,您可以使用reserve而不是resize或使用m對象進行初始化。它只會分配內存,而不會構建不會使用的對象的開銷,從而增加初始化速度。

而且,只有在有效使用它之前,向量的加載容量纔會消耗虛擬內存,而不是真正的內存。

如果你知道內部向量大小的分佈,使用平均值作爲默認長度,它可以幫助你減少內存浪費。

在任何情況下,std::list是一個更大的空間浪費,並考慮到碎片更糟。

+0

感謝您的全面回答。通常,m至少比n大5或10倍。原因在於m是最大容量是因爲我使用嵌套向量作爲對n個容器中的m個對象進行排序的手段,這實際上是一個鴿子洞原理。這意味着一些嵌套向量可能是空的。每次運行算法需要清除並重新填充Ar 60次。過去我有一些嵌套列表的問題,所以也許是因爲這種經驗而產生偏執。將嘗試與我正在做的事情,並實施調整,如果有麻煩。 – Plamen

+0

奇怪的是,我沒有在使用嵌套列表的實際內存中增加......無論如何,使用嵌套向量的實現速度要快得多,所以如果內存問題變得非常緊縮,我將使用上面提到的技術之一。 – Plamen

+1

當你說你沒有記憶增量時,你引用了什麼?另外,我非常肯定,碎片不會是一個問題:或者你的向量相對較小,最終不需要調整大小,並且會保留它們的第一個分配空間,要麼它們很大,然後內存訪問有點連續。問題可能在於,如果您需要經常調整它們的大小,那麼可以通過'reserve'方法阻止這個問題,而不會浪費太多內存:) – rems4e

0

也許resize函數將幫助你。詳情請參閱here

+0

在該示例中,行中的條目數是先驗衆所周知。就我而言,我不知道每個嵌套向量將包含多少個條目,或者它們何時將被添加。把它看成是一個潛在的問題。你是否建議我在每次向嵌套向量添加條目時調整大小? – Plamen

+0

這不是一個好的解決方案,但是權衡取決於我沒有的參數(例如更改的數量和頻率)。您可能總是調整大於1的遞增(各種滯後) – levengli

相關問題