我发现sclarke81和Sam Robert的答案实际上都不起作用,我怀疑预分配的概念是否适用于matfile.下面报告的结果是在具有16.8 GB主内存的i7-3770 CPU @ 3.4 GHz上获得的,在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倍,并且没有太大变化.奇怪.顺便说一句,最后清楚的是确保文件由Matlab编写和关闭.
通常我们想要将初始化预分配到NaN而不是0.按照接收的方式执行此操作
mf = matfile(fn, 'Writable', true);
mf.x = nan(5000, 200000);
clear mf
需要11秒,结果是57 MB的文件.但正如OP指出的那样,这种方法没有意义,因为它首先在内存中生成8 GB的整个矩阵然后将其写出来,这违背了matfile的目的.如果矩阵适合内存,那么首先没有理由在处理文件时将数据保存在文件中.
Sam Roberts建议首先如上所述分配/初始化为0,然后将值更改为NaN:
mf = matfile(fn, 'Writable', true);
mf.x(5000, 200000) = 0;
mf.x = mf.x * nan;
clear mf
这需要16秒,具有相同的结果文件大小.然而,这绝不比上面的天真方法更好,因为在第三行上,整个矩阵被读入内存,与标量NaN在内存中相乘,然后再次写出,导致8 GB的峰值内存消耗. (这不仅与documentation中解释的matfile-variables的语义一致,而且还检查了内存使用情况监视器.)
sclarke81建议用这种方式避免在内存中生成矩阵:
mf = matfile(fn, 'Writable', true);
mf.x(1 : 5000, 1 : 200000) = nan;
clear mf
这个想法可能只是在内存中只生成一个标量NaN,然后复制到磁盘矩阵的每个元素中.然而,事情并非如此.事实上,这种方法在峰值时似乎消耗了大约8.38 GB的内存,比天真的方法多12%!
现在更多关于使用matfile预分配的优点.如果没有预先分配,但用NaNs逐行填充数组
mf = matfile(fn, 'Writable', true);
for i = 1 : 5000
mf.x(i, 1 : 200000) = nan(1, 200000);
end
clear mf
这需要27秒.但是,如果一个prerateocates初始化为0然后逐行覆盖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
这需要很长时间:当我在45分钟后中止它时,这个过程只有大约3%完成,推断到总运行时间约一天!
matlab.io.MatFile的行为是黑暗而神秘的,似乎目前只有广泛的测试才能有效地使用这个设施.但是,可以得出结论,在matfile方面,预分配是一个坏主意.