簡體   English   中英

C - 是否將數組重新分配到數組,其大小是動態數據結構中的兩倍?

[英]C - Is realloc'ing arrays to arrays twice the size efficient in dynamic data structures?

最近我用C編寫了很多代碼,我注意到,在我的程序中占用大部分時間的事情是調整動態數據結構的大小。 假設我們有一個包含字符的數組,我想在這個數組的末尾添加一些字符。 我這樣做:

  1. 檢查是否分配了足夠的內存。
  2. 如果沒有,realloc數組到大小兩倍的數組(使用realloc)
  3. 如果現在有足夠的內存,請附加字符,否則轉到第2點。

我只是想知道這是否足夠有效。 例如,我可以想到像樹結構這樣的東西,我將數組保存在樹的節點中,這樣,而不是在追加東西之前將舊元素復制到新數組,我只是將新的malloc'ed元素添加到下一個樹的節點並在那里附加字符。 這樣我就可以避免不必要的復制......

所以這只是以不同方式調整大小的一種方式。 我應該尋找其他的東西,還是我只是將舊元素復制到新數組的兩倍大小的解決方案?

與所有“最有效”的問題一樣,唯一可以知道的方法是衡量現實條件下的實際表現。

一般來說,在連續的內存位置中擁有項目可以獲得很大的性能提升,因為對於任何一個接一個地處理項目的算法來說,這幾乎總是緩存最友好的布局。 總的來說,連續數組也占用較少的空間,因為您不需要額外的空間來存儲其他數據(如樹節點)。

雖然在需要增長時將尺寸加倍是一種常見的方法,但它可能會占用地址空間。 一些STL實現將矢量的結構增加1.5倍而不是2倍以避免某些病態情況。 在短期內,這會導致更多的分配,但可以減少內存碎片。 如果您使用realloc,這可能適用也可能不適用。 這取決於realloc成功執行的頻率。

通常任何具有對數時間復雜度的東西(如重新分配算法)都被認為是“足夠好”。 通常,您只能使用塊列表保存復制操作,但您仍然必須訪問新塊的免費存儲,這總是比較昂貴。

您最好的選擇可能是為預分配執行合理的啟發式操作,以便在大多數情況下避免重新分配。 今天記憶很豐富,至少如果其他人表現出一些紀律;-)。

接受答復后

效率取決於許多問題,包括和分析將為給定的淤積提供一個想法。

當然,通過鄰近的比例因子(如2.0,1.5或其他東西)增長會提供一個很好的對數增長。

2問題不在其他地方:收縮和樂觀分配。

收縮:結構不僅會增長,還會縮小。 與增長一樣,減少應該是對數的。 然而,如果增長/減少的閾值相似,則可以發生減少。 建議增長和收縮閾值以對數方式均勻分布。 示例:4x步驟,

增長大小1,4,16,64,256 ......
收縮2,8,22,128 ......

樂觀分配:具有大內存容量的處理器使用的虛擬地址空間通常遠大於物理地址空間。 在分配內存時,例如1,000,000,在使用之前不會分配真正的物理內存 - (例如設置為非零)。 即便如此,它僅用於某些頁面大小的塊,如4k或64k字節。 請參閱為什么malloc沒有“耗盡”我計算機上的內存?

將分配增加兩倍的基本思想是可靠的,因為它使平均重新分配與最大數組大小成線性關系(由於一半對象永遠不會移動,每個對象平均移動一次)。

我在您的實現中看到的唯一可優化的點是,當數組的大小必須跳轉時重新分配幾次:如果您有一個64字節的數組並且需要4096字節,則realloc()調用第一個副本64個字節,然后128個字節(其中64個是未初始化的),然后是256個字節,依此類推,總共復制4032個字節,在途中進行6個分配。 然而,所需要的只是獲取4096字節的內存並復制64字節。 編寫代碼的方式是在增加分配時最多調用realloc()一次。

可以扼殺性能的另一點是起始尺寸太小。 malloc()調用需要超過250個CPU周期,並且分配的開銷至少有兩個指針大小的值。 您希望確保這些成本相對於內存使用量而言較小。 因此,對於僅一個元素使用初始分配通常沒有意義。 您希望確保初始分配至少在64字節(25%的空間開銷)范圍內。

重新分配數組肯定不是最有效的。 Realloc確保連續的內存塊。 由於這可能無法實現,因此realloc最終可能會分配新的內存塊,將所有數據復制到其中,並釋放原始內存塊。 這可能非常昂貴,因為它是數據大小的線性操作,具有相當大的恆定開銷。

您應該真正評估是否需要連續的內存塊(您描述的樹結構是非連續數據結構的示例)。 如果你這樣做,你應該嘗試提出一種技術來估計你需要多少內存,並盡量減少重新分配。

在我看來,您可以將數據存儲在指向其他字符數組的指針數組中。 由於頂級數組僅存儲指針,因此您可以將其預分配足夠大以用於所有實際用途。 但是,我不太了解你的問題,推薦一個合適的解決方案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM