图中红色的序号即为数组在内存中的存储顺序。在程序中对数组进行索引或赋值时,如果能够按照这种顺序来存储,一方面可以利用计算机的缓存机制,另一方面可以避免程序在内存中的不断跳转,从而可以显著地提高程序的运行效率。如果通过多重循环来存取数据,遵照此原则,最内层循环应该遍历最低维(列),从内向外,依次向高维过渡。
下面的程序可以比较预分配内存和索引顺序对程序运行时间的影响:
% 数组索引效率比较
clear
preAllocate = 'on'; %设为off关闭预分配内存
r = 10000;c = 10000;
tic
if isequal(preAllocate,'on')
A = zeros(r,c); %预分配内存
else
preAllocate = 'off';
end
for m=1:r %行优先
for n=1:c
A(m,n) = m+n;
end
end
fprintf('行优先,预分配内存 %s, 耗时 \t%f\n',upper(preAllocate),toc)
tic
if isequal(preAllocate,'on')
B = zeros(r,c); %预分配内存
end
for n=1:c %列优先
for m=1:r
B(m,n) = m+n;
end
end
fprintf('列优先,预分配内存 %s, 耗时 \t%f\n',upper(preAllocate),toc)
看一下不同情况下的耗时对比
行优先,预分配内存 OFF, 耗时 407.735436
列优先,预分配内存 OFF, 耗时 1.346732
行优先,预分配内存 ON, 耗时 1.149516
列优先,预分配内存 ON, 耗时 0.412534
可以看出,内存使用不当可以造成近千倍的效率差别。是因为MATLAB慢吗?
一言以蔽之,为数组预分配内存并遵循“列优先”的原则使用数组中的数据,是提高MATLAB效率的有效途径。
几点说明: