2013-07-15 44 views
1

我需要在程序中自動創建變量。我寫了下面的MATLAB代碼來創建唯一的變量併爲它們賦值。但是,eval需要很長時間。在MATLAB中減少分配時間

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

知道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 

要訪問的單元在(Ĵ)位置,使用大括號({}),例如wave{1, 2}是單元的位置處的內容(1,2)。

另請注意,我已將strcat替換爲sprintf。更高雅,不是嗎?

+1

非常感謝。它工作:D –

+0

@amirnemat樂於幫助:) –

0

我不能評價eval,因爲我沒有這些波形文件,但沒有EVAL線,你可以做如下:

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.09s我的電腦上,相比於0.946s的原始代碼(沒有評估)。

和U也很可能做到這一點應該是更快:

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 

並行讀取可以做如下(小基於埃坦牛逼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; 

但瓶頸可能是從硬盤讀取多個文件的速度比讀取一個文件要慢。也許少工人會更好。

+0

感謝您的回覆。但我想執行「wavread」命令。該命令從輸入地址讀取波形文件並將其分配給name1。我想更快地做到這一點。 –

+0

@amirnemat使用parfor並行讀取什麼? – Marcin

+0

如何使用parfor讀取並行?如果您可以編寫MATLAB代碼,我將非常感激。 –