我以前写代码常常写出
for n = 1 : xxx
a(n) = fcn(....)
end
后来到处偷师,学了到一定要先开内存,比如用zeros(), 比如换成 for n = xxx : -1 :1
Matlab 在使用内存的时候最有效率的方法是一次找到足够大的连续内存块,而for显然在有些情况下无法满足。
下面写了几个例子。
特别推荐的是
for n = len : -1 :1 的这种for的写法,即不需要zeros() 之类的先开内存,也可以达到预分配内存的效果,当然不知道
是不是某个版本改进之后的效果。
主要的问题来自于matlab的内存管理机制:
对于一个数组,matlab先在内存中找一块放得下的连续空间,如果这个数组一直增大到那个连续空间放不下了,
matlab会去找另外一个放得下的连续空间(好像记得在什么地方听到过是找一个原来内存2倍大的地方),这样就带了
两个问题:
1. 额外的操作,找内存 + 复制; 而且这种操作有可能是很多次。
2. 额外的空间,这个时候有2份copy在内存中。导致内存不足的常见原因之一
% Test Part I
clear;
clc;
len = 1000;
LOOP = 100;
tic;
for t = 1 : LOOP
for n = 1 : len
for m = 1:len
x(n,m) = n*m;
end
end
end
t1 = toc;
clear x;
tic;
x = zeros(len);
for t = 1 : LOOP
for n = 1 : len
for m = 1:len
x(n,m) = n * m;
end
end
end
t2 = toc;
clear x;
tic;
for t = 1 : LOOP
for n = len : -1 : 1
for m = len : -1 : 1
x(n,m) = n * m;
end
end
end
t3 = toc;
clear x;
msg = sprintf('Part I: Loop 1 is %5.1f \n\tLoop 2 is %5.1f\n\tLoop 3 is %5.1f',t1,t2,t3);
disp(msg);
% Test Part II
len = 1000;
tic;
for n = 1 : len % Loop 1
for i = 1 : len
x(i+(n-1)*i) = n*i;
end
end
t1 = toc;
clear x;
tic;
x = zeros(len*len,1);
for n = 1 : len % Loop 2
for i = len: -1 : 1
x(i+(n-1)*i) = n*i;
end
end
t2 = toc;
clear x;
len = 1000;
tic;
for n = len : -1 : 1 % Loop 3
for i = len : -1 : 1
x(i+(n-1)*i) = n*i;
end
end
t3 = toc;
clear x;
msg = sprintf('Part II: Loop 1 is %5.1f \n\tLoop 2 is %5.1f\n\tLoop 3 is %5.1f',t1,t2,t3);
disp(msg);