Ich fand, dass weder sclark81 noch Sam Roberts Antworten tatsächlich funktionieren, und ich bezweifle, dass das Konzept der Vorallokation auf gilt. Die unten angegebenen Ergebnisse wurden auf einer i7-3770-CPU bei 3,4 GHz mit 16,8 GB Hauptspeicher, auf dem Matlab R2013a unter Linux 3.16 läuft, erhalten.
Der Code
mf = matfile(fn, 'Writable', true);
mf.x(5000, 200000) = 0;
clear mf
theoretisch 8 GB Speicher auf der Festplatte hat jedoch die resultierende Datei nimmt eine Größe von 4726 Bytes, und das Verfahren weniger als 0,01 Sekunden, initialisiert auf 0 „weist“. Ich kann die Größe 10- oder 100-fach vergrößern, und es ändert sich nicht viel. Seltsam. Btw., Die clear
am Ende ist da, um sicherzustellen, dass die Datei von Matlab geschrieben und geschlossen wird.
Oft wollen wir NaN vorzubelegen Initialisierung statt 0 Dadurch wird die Weise
erhielt
mf = matfile(fn, 'Writable', true);
mf.x = nan(5000, 200000);
clear mf
11 Sekunden, und Ergebnisse in einer Datei von 57 MB nimmt. Aber wie das OP darauf hingewiesen hat, macht dieser Ansatz keinen Sinn, da er zunächst die gesamte 8-GB-Matrix im Speicher erzeugt und dann ausschreibt, was den Zweck von vereitelt. Wenn die Matrix in den Speicher passt, gibt es zunächst keinen Grund, die Daten während der Verarbeitung in einer Datei zu speichern.
Sam Roberts vorgeschlagen ersten zuzuteilen/initialisieren, wie oben auf 0 und dann um die Werte ändern NaN:
mf = matfile(fn, 'Writable', true);
mf.x(5000, 200000) = 0;
mf.x = mf.x * nan;
clear mf
Dies dauert 16 Sekunden, mit der gleichen resultierenden Dateigröße. Dies ist jedoch in keiner Weise besser als der oben beschriebene naive Ansatz, da in der dritten Zeile die gesamte Matrix in den Speicher eingelesen, mit dem skalaren NaN im Speicher multipliziert und dann wieder ausgeschrieben wird, was zu einem Spitzenspeicherverbrauch von 8 GB führt. (Dies ist nicht nur im Einklang mit der Semantik von matfile
-Variablen im documentation erklärt, aber ich habe auch mit einem Speichernutzung Monitor überprüft.)
sclarke81 auf diese Weise statt zu vermeiden Erzeugung der Matrix im Speicher vorgeschlagen:
mf = matfile(fn, 'Writable', true);
mf.x(1 : 5000, 1 : 200000) = nan;
clear mf
Die Idee ist wahrscheinlich, dass nur ein skalares NaN im Speicher generiert und dann in jedes Element der On-Disk-Matrix kopiert wird. Das passiert jedoch nicht. In der Tat scheint diese Methode etwa 8,38 GB Speicher in der Spitze zu verbrauchen, 12% mehr als der naive Ansatz!
Jetzt mehr auf die Vorzüge der Vorbelegung mit . Wenn man nicht voreilt, sondern das Array zeilenweise mit NaNs füllt, dauert dies 27 Sekunden. Aber, wenn man weist ihn vorab auf 0 initialisiert und dann zeilenweise Überschreibungen von NaNs
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
es dauert ewig: Der Prozess wurde nur etwa 3% fertig, als ich es nach 45 Minuten abgebrochen, auf etwa eine Extrapolation Tag der gesamten Laufzeit!
Das Verhalten von matlab.io.MatFile
ist dunkel und mysteriös, und es scheint, dass im Moment nur ausgiebige Tests zu einem effektiven Weg führen, diese Einrichtung zu nutzen. Man kann jedoch zu dem Schluss kommen, dass die Vorabzuweisung eine schlechte Idee ist, wenn es um geht.
Hmm, verwandte Frage Ich nehme an, ob es * Notwendigkeit * gibt, in diesem Fall vorzugeben. Der übliche Leistungsvorteil wird vermutlich trivial im Vergleich zu der Zeit sein, die benötigt wird, um Material auf Disc zu schreiben ... denke, es vermeidet, dass die Datei fragmentiert wird? – Flyto