2013-07-15 2 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 по своей сути медленный и редко полезный.

Вместо различных переменных wave1, wave2 ... почему вы не используете 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 

Чтобы получить доступ к ячейке на месте (я, J), используйте фигурные скобки ({}), например 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 исходного кода (без eval).

И у могли бы также, вероятно, сделать это, которое должно быть еще быстрее:

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 

Чтения параллельно может быть сделано следующим образом (немного на основе Эйтан 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; 

Но узкое место может быть то, что чтение многих файлов одновременно с жесткого диска происходит медленнее, чем чтение одного файла. Может быть, меньше рабочих будет лучше.

+0

Спасибо, что ответили. Но я хочу выполнить команду «wavread». Это commend прочитает волновой файл с входного адреса и назначит ему имя1. Я хочу сделать это быстрее. –

+0

@amirnemat как насчет чтения параллельно, используя парформу? – Marcin

+0

Как читать параллель с помощью parfor? Я буду очень благодарен, если бы вы могли написать код MATLAB. –

Смежные вопросы