我發現sclarke81和Sam Robert的答案都沒有效果,我懷疑預分配的概念適用於matfile
。以下報告的結果是在i7-3770 CPU @ 3.4 GHz,16.8 GB主存儲器上運行,在Linux 3.16上運行Matlab R2013a。
代碼
mf = matfile(fn, 'Writable', true);
mf.x(5000, 200000) = 0;
clear mf
理論上「分配」 8 GB的磁盤存儲器,初始化爲0。然而,所得到的文件的大小爲4726個字節,並且這一過程需要小於0.01秒。我可以將尺寸增加10倍或100倍,沒有太大的變化。奇怪。順便提一下,clear
最後是確保文件是由Matlab編寫和關閉的。
我們經常要預分配初始化爲NaN,而不是0這樣做的收到方式
mf = matfile(fn, 'Writable', true);
mf.x = nan(5000, 200000);
clear mf
需要11秒,結果在57 MB的文件。但正如OP指出的那樣,這種方法沒有任何意義,因爲它首先在內存中生成8 GB的整個矩陣,然後將其寫出,這違背了matfile
的目的。如果矩陣適合內存,那麼在處理數據時首先沒有理由將數據保存在文件中。
薩姆羅伯茨提議第一分配/初始化爲0如上述,然後改變數值爲NaN:
mf = matfile(fn, 'Writable', true);
mf.x(5000, 200000) = 0;
mf.x = mf.x * nan;
clear mf
這需要16秒,用相同的生成的文件大小。但是,這並不比上面的簡單方法更好,因爲在第三行,整個矩陣被讀入內存,乘以內存中的標量NaN,然後再次寫出,導致峯值內存消耗爲8 GB。 (這不僅與matfile
- 變量語義一致,在documentation解釋,但我也有一個內存佔用監視器檢查。)
sclarke81建議,而不是避免產生矩陣的記憶是這樣的:
mf = matfile(fn, 'Writable', true);
mf.x(1 : 5000, 1 : 200000) = nan;
clear mf
這個想法可能是在內存中只生成一個標量NaN,然後複製到磁盤矩陣的每個元素中。但是,那不是什麼情況。事實上,這種方法似乎在高峯期消耗大約8.38 GB的內存,比天真的方法高出12%!
現在更多關於與matfile
預分配的優點。如果不預先分配,但用NaN逐行填充陣列
mf = matfile(fn, 'Writable', true);
for i = 1 : 5000
mf.x(i, 1 : 200000) = nan(1, 200000);
end
clear mf
這需要27秒。 但,如果一個預先分配初始化爲0和NaN的,然後按行改寫
mf = matfile(fn, 'Writable', true);
mf.x(5000, 200000) = 0;
for i = 1 : 5000
mf.x(i, 1 : 200000) = nan(1, 200000);
end
clear mf
它需要年齡:當我在45分鐘後中止它,外推至一個過程只有約3%完成總運行時間爲!
matlab.io.MatFile
的行爲是黑暗而神祕的,看來目前只有廣泛的測試才能導致使用這種設施的有效方法。但是,有人可能會得出結論:預分配對於matfile
來說是個壞主意。
嗯,相關的問題我想是否有任何*需要*預先分配在這種情況下。通常的性能優勢大概會比寫入光盤所花費的時間微不足道。猜猜它能避免文件被分割? – Flyto 2014-10-01 11:01:50