减少MATLAB中的赋值时间

时间:2013-07-15 02:28:11

标签: performance matlab eval

我需要在程序中自动创建变量。我编写了以下MATLAB代码来创建唯一变量并为它们赋值。但是,eval需要花费很多时间。

for i=1:22
    for j=1:54
        s=strcat(num2str(i),num2str(j));
        name1=strcat('wave',s);
        add=strcat('F:\MIT Corpus\train\f',num2str(i),'\phrase0',num2str(j),'_16k.wav'); 
        (eval( [ sprintf(name1) '=wavread(add)'] ));
    end
end

有没有办法让这段代码运行得更快?

2 个答案:

答案 0 :(得分:2)

知道eval本质上很慢,很少有用。

取代不同的变量wave1wave2 ...为什么不使用cell array

for ii = 1:22
    for jj = 1:54
        name1 = strcat('wave',s);
        str = sprintf('F:\\MIT Corpus\\train\\f%d\\phrase0\\%d_16k.wav', ii, jj);
        wave{ii, jj} = wavread(str);
    end
end

要访问( i j )位置的单元格,请使用花括号({}),例如wave{1, 2}是位置(1,2)处的细胞内容。

另请注意,我已将strcat替换为sprintf。更优雅,不是吗?

答案 1 :(得分:0)

我无法评估eval,因为我没有这些wave文件,但如果没有eval line,您可以执行以下操作:

for i=1:22
    istr = int2str(i);
    for j=1:54        
       jstr = int2str(j);
       name1= ['wave',jstr, jstr ];    
       add = ['F:\MIT Corpus\train\f', istr, '\phrase0',jstr,'_16k.wav'];
      % eval( [ sprintf(name1) '=wavread(add)'] );
    end
end

这个更改在我的电脑上需要0.09秒,相比原始代码的0.946秒(没有评估)。

你也可以这样做,这应该更快:

  for i=1:22
        istr = int2str(i);
        for j=1:54        
           jstr = int2str(j);   
           add = ['wave',jstr, jstr, '=wavread(F:\MIT Corpus\train\f',      istr,'\phrase0',jstr,'_16k.wav)'];
          % eval( add );
        end
    end

并行阅读可以如下进行(很少基于Eitan T anwser):

% close matlabpool if exists
if  matlabpool('size') > 0
    matlabpool close;
end     


% no of wave files to read
NO_OF_FILES = 22*54;

% preallocate waveCell for files to be readed into
waveCell = cell(1, NO_OF_FILES);


% make ii and jj wave string names to be used 
waveNameCell = cell(1, NO_OF_FILES);

idx = 1;
for ii = 1:22
    for jj = 1:54
        waveNameCell{idx} = {int2str(ii), int2str(jj)};
        idx = idx + 1;
    end
end

% create 6 matlab workers (6 is max default in 2013a),
% if u want more, matlab will give en error
% but will also tell how to change it to more, very easy. 
% Off course, its best to how no more workers than cores/threads/cpus, etc.
matlabpool(6);    

% execute this loop in parallel using matlab workers
% each worker will read one wave file
parfor wavei = 1:NO_OF_FILES

    waveName = waveNameCell{wavei};

    ii = waveName{1};
    jj = waveName{2};

    str = sprintf('F:\\MIT Corpus\\train\\f%d\\phrase0\\%d_16k.wav', ii, jj);


    waveCell{wavei} = wavread(str);; 
end    



matlabpool close;

但瓶颈可能是从硬盘驱动器同时读取多个文件比读取一个文件慢。也许更少的工人会更好。