Matlab 代码速度测试和内存使用测试
使用matlab处理比较大的数据时候,我们会遇到out of memory 的情况,这种情况下就需要我们优化代码,来节省内存。我在处理一个超大矩阵的傅里叶变换过程中,测试了不同的代码及内存使用情况,这里和大家分享一下。
需要傅里叶变换的矩阵A[1,250200,64]
初始变量定义:
bMax=1;
NMax=250200;
SampleMax=64;
s=1;
第一中,使用for循环来读取数据,使用for 循环来进行FFT变换,
v=zeros(bMax,NMax,SampleMax);
dt = timestep*dumpstep;%time between the dump frame
fid1=fopen(['Velocity1.txt'],'r');%%读入数据
tic
for b=1:bMax;
for f=1:SampleMax;
data_v=textscan(fid1,'%f',NMax);
save (['data_v',num2str(s),'.mat'],'data_v');
v(b,1:NMax,f)=data_v{1};
end;
toc
end;
fclose(fid1);
tic
for j=1:1:NMax;
m(bMax,1,1:SampleMax)=fft(v(bMax,j,:),[],3)*dt;
v(bMax,j,1:SampleMax)=m(bMax,1,1:SampleMax);%this is the fft part
end;
toc
Memory used by MATLAB: 2408 MB (2.525e+09 bytes)
Elapsed time is 8.434202 seconds. 数据读取时间
Elapsed time is 64.259465 seconds. 傅里叶变换时间
第二种,使用for循环读取数据,使用中间变量矩阵进行FFT变换,
v=zeros(bMax,NMax,SampleMax);
m=zeros(bMax,NMax,SampleMax);
dt = timestep*dumpstep;%time between the dump frame
fid1=fopen(['Velocity1.txt'],'r');
tic
for b=1:bMax;
for f=1:SampleMax;
data_v=textscan(fid1,'%f',NMax);
save (['data_v',num2str(s),'.mat'],'data_v');
v(b,1:NMax,f)=data_v{1};
end;
toc
end;
fclose(fid1);
tic
m(bMax,1:NMax,1:SampleMax)=fft(v(bMax,1:NMax,:),[],3)*dt;
v(bMax,1:NMax,1:SampleMax)=m(bMax,1:NMax,1:SampleMax);%this is the fft part
toc
Memory used by MATLAB: 2652 MB (2.781e+09 bytes)
Elapsed time is 8.485230 seconds.
Elapsed time is 1.290618 seconds.
FFT变换的时间变短,但是中间变量占据内存使得总的需要的内存变大。
对于matlab的傅里叶变换,矩阵操作比for循环效率高。
第三种,使用for循环读取数据,不使用中间变量矩阵进行FFT变换,将FFT变换之后的结果直接付给原来的矩阵。
v=zeros(bMax,NMax,SampleMax);
dt = timestep*dumpstep;%time between the dump frame
fid1=fopen(['Velocity1.txt'],'r');
tic
for b=1:bMax;
for f=1:SampleMax;
data_v=textscan(fid1,'%f',NMax);
save (['data_v',num2str(s),'.mat'],'data_v');
v(b,1:NMax,f)=data_v{1};
end;
toc
end;
fclose(fid1);
tic
v(bMax,1:NMax,1:SampleMax)=fft(v(bMax,1:NMax,:),[],3)*dt;
toc
Memory used by MATLAB: 2408 MB (2.525e+09 bytes)
Elapsed time is 8.791504 seconds.
Elapsed time is 0.892415 seconds.
发现这种情况下,内存的使用减少。也就是说,在matlab中,使用matlab内置的函数对一个矩阵进行操作时,并且把操作的结果返回给原来的矩阵,根据第一种和第三种使用的内存一样,可以看出这种操作的流程如下:
对矩阵A中的某一维进行操作,计算出结果,将结果返回A中的这一维,接着对A中的另外一维进行操作,依次进行下去,而不是对A中的全部维进行操作,存在临时变量中,再将所有的结果统一赋值给矩阵A。
同时我也测试了for循环读取数据和直接load 的速度,for 循环读取数据的速度高于load。