我知道這是一個古老的問題,但有幾件事似乎每個人都失蹤了。
首先,這是乘以2:尺寸< < 1.這是通過1和2之間的任何乘法:INT(浮動(大小)* x),其中x是數量,*是浮點數學,並且處理器必須在float和int之間運行額外的指令。換句話說,在機器級別,加倍需要一個非常快速的指令來查找新的大小。通過1和2之間的東西乘以要求至少一個指令投尺寸爲浮點數,一個指令乘以(這是浮動乘法,所以它可能需要至少兩倍的週期,如果不是4或甚至8倍很多),以及一個指令投退爲int,並假定你的平臺可以對通用寄存器執行,而不需要使用特殊寄存器浮點運算。總之,您應該期望每次分配的數學計算至少需要十次,只要簡單的左移。如果您在重新分配期間複製大量數據,這可能沒有多大區別。
其次,也許是最大的踢球者:每個人似乎都認爲正在被釋放的內存既與自身連續,又與新分配的內存連續。除非您自己預先分配所有內存,然後將它用作池,否則幾乎肯定不是這種情況。操作系統可能偶爾會在這樣做,但大多數情況下,將會有足夠的空閒空間碎片,任何一半體面的內存管理系統都能夠找到一個小小的空間,您的內存將適合您。一旦你真的有點大塊,你很可能會結束連續的片斷,但是到那時,你的分配足夠大,以至於你沒有足夠頻繁地進行分配,因爲它不再那麼重要。簡而言之,設想使用一些理想的數字可以最有效地使用可用內存空間是很有趣的,但事實上,除非您的程序在裸機上運行,否則不會發生這種情況(因爲沒有OS在它下面做出所有決定)。
我對問題的回答是?不,沒有理想的數字。這是特定應用程序,甚至沒有人真正嘗試。如果你的目標是理想的內存使用情況,那麼你幾乎沒有運氣。對於性能而言,分配的頻率越低越好,但如果我們這樣做,我們可以乘以4甚至8!當然,當Firefox一次性使用1GB跳到8GB時,人們會抱怨,所以甚至沒有意義。這裏有一些經驗法則,我會去:
如果你不能優化內存使用,至少不要浪費處理器週期。乘以2至少比做浮點數學運算快一個數量級。它可能沒有太大的區別,但至少會有所作爲(特別是在更頻繁和更小的分配期間)。
不要過時。如果你花了4個小時試圖弄清楚如何完成已經完成的工作,那麼你就浪費了時間。完全誠實地說,如果有一個比* 2更好的選擇,它將在幾十年前的C++向量類(以及許多其他地方)中完成。
最後,如果你真的想優化,不要汗流small背的東西。現在,沒有人關心浪費4KB內存,除非他們在嵌入式系統上工作。當你獲得1GB到1MB到10MB之間的對象時,加倍可能太多了(我的意思是,這是100到1,000個對象)。如果您可以估計預期的擴張速度,那麼您可以在某個點將其平穩增長至線性增長率。如果您期望每分鐘大約10個物體,那麼每個步驟以5到10個物體大小(每30秒到一分鐘一次)增長可能沒問題。
這一切都歸結爲,不要過多考慮,優化可以使用的內容,並在必要時自定義到您的應用程序(和平臺)。
詳細說明,將數組大小加倍意味着您可以獲得** amotized ** O(1)個插入。 這個想法是,每當你插入一個元素,你也複製舊數組中的一個元素。 假設你有一個大小爲_m_的數組,其中有_m_個元素。添加元素_m + 1_時,沒有空格,因此您分配了一個尺寸爲_2m_的新數組。每次插入新元素時,不要複製所有第一個_m_元素,而是複製一個元素。這將最小化差異(除了內存分配),並且一旦你插入了2m元素,你將複製舊數組中的所有元素。 – hvidgaard 2014-11-04 10:06:38