2014-01-30 6 views
1

У меня есть следующая проблема: у меня есть код для поиска в больших файлах, содержащих данные, процесс становится слишком медленным, и даже на некоторых компьютерах он потребляет все доступные компьютерные ресурсы.Чтение внешних файлов более эффективно в MATLAB

nodo=str2num(get(handles.nodo,'string'));         
PATHNAME = uigetdir('', 'Selecciona el directorio donde están los bfins'); 
files = dir(fullfile(PATHNAME,'*.bfin'));         
curr_folder=pwd;               
cd(PATHNAME);                
archivo={files.name}';              
for i=1:numel(archivo)              
     [fid{i}, errmsg]=fopen(files(i).name)         
     disp(errmsg);               
     Datos{i}=textscan(fid{i}, '%s %f %s %f %s %f ','Headerlines',2);  
     AllNodos{i}=Datos{1,i}{1,2};           
     AllTemp{i}=Datos{1,i}{1,4};           
end                  
cd(curr_folder)               
for i=1:size(AllNodos,2)             
     sets{i}=cat(2, AllNodos{1,i}, AllTemp{1,i});       
end                  
for i=1:size(AllNodos,2)             
     vectn{i}=AllNodos{1,i};            
     r{i}=find(vectn{i}==nodo);            
     Temps{i}=AllTemp{1,i}(r{i});           
end 
    %Write Excel File 
[FileName, PathName] = uiputfile('*.xlsx', 'Escribe un archivo excel con las temperaturas...') 
savingas=fullfile(PathName,FileName); 
a=archivo'; 
B=cat(1,a,Temps); 
xlswrite(savingas,[B]) 
e = actxserver ('Excel.Application'); %# open Activex server 
ewb = e.Workbooks.Open(savingas); %# open file (enter full path!) 
ewb.Worksheets.Item(1).Name = num2str(nodo); %# rename 1st sheet 
ewb.Save %# save to the same file 
ewb.Close(false) 
e.Quit                

Что код действительно должен найти и файлы расположение строки, а затем найти другую переменную (только Управлен + п операции) и воспроизводить их в листе первенствовать помощь относительно этого будет оценили.

EDIT ---- Большое спасибо за все ваши комментарии, я придумал следующий код, который экономит много времени unnecesary, что он используется для хранения брать переменных:

for i=1:num_archivo 
    [fid(i), errmsg]=fopen(files(i).name) 
    disp(errmsg); 
    Datos=textscan(fid(i), '%s %f %s %f','delimiter',',','HeaderLines',hl); 
    AllNodos=Datos(1,2); 
    AllTemp=Datos(1,4); 
    for k=1:numel(nodo) 
    r{i,k}=find(AllNodos{1,1}==nodo(k)); 
    Temps{i,k}=AllTemp{1,1}(r{i,k}); 
    end 
    end 
+0

Какой размер файлов, примерно и сколько файлов мы говорим? – sebastian

+0

Файлы размером около 25 Мбайт, и около 8 файлов для обработки – user2751649

ответ

1

textscan сам по себе очень быстро, поэтому он может потреблять процессор, но вы вряд ли улучшите его по производительности. Однако похоже, что вы не выполняете какое-либо предварительное выделение для своих ячеек. Это означает, что Matlab может постоянно перераспределять память. Используйте cell, чтобы создать пустой массив ячеек нужного размера: (. Хотя Datos, вероятно, не должна быть клетка на @Lazarus указал)

num_archivo = numel(archivo); 
Datos = cell(1,num_archivo); 
AllNodos = cell(1,num_archivo); 
AllTemp = cell(1,num_archivo); 
for i = 1:num_archivo 
    ... 
end 
... 

Вы должны делать то же рода вещи для других петель с sets , vectn и т.д.

Еще одна вещь, которую я бы обязательно сделать вызов fclose(fid); сразу после того, как вы закончите чтение files(i).name так, что вы не имеете кучу открытых указателей файлов. Кроме того, нет никаких причин для сохранения файла id fid в массив ячеек, поскольку вы не используете его за пределами цикла. Даже если бы вы это сделали, регулярный вектор (выделенный с помощью numel(archive) элементов) был бы лучше.

1

Мои ответ будет зависеть от того, насколько велики ваши наборы данных. Но первое изменение, которое я бы сделал, - установить Datos{i} только Datos, поскольку вы используете его только в цикле for. Таким образом, Matlab не должен выделять больше места.

Второе изменение, которое я хотел сделать это, чтобы включить функцию, cat и find в рамках первого цикла для, так что вы можете также заменить Allnodos{i} с Allnodos, а также сэкономить на вопросе распределения.

Это должно помочь в решении проблемы с ресурсами; это может не помочь в решении проблемы скорости, если textscan является ограничивающим фактором. Используя tic и toc до и после того, как textscan сообщит вам, сколько времени оно занимает.

+0

Не могли бы вы более конкретно узнать о своем решении ?, я попробовал то, что вы сказали, но я получаю ошибку «индекс превышает размеры матрицы», хэнк для вашей помощи. – user2751649

+0

Какая строка дала вам ошибку? – Lazarus

1

Это зависит от размера ваших «больших» файлов и количества их. Проверьте код с помощью профайлера:

profile on; 
<run your code> 
profile viewer 

Я подозреваю, что fopen и textscan линии злые ...

Вообще в чем-либо относительно чтения файлов, узким местом является главным образом диск я/o - не CPU. В этом случае вы не можете сделать много, кроме как делать что-то параллельно, возможно, что, к сожалению, не так просто в Matlab - если вы не готовы платить.

+0

Можете ли вы подробно рассказать о параллельной операции, я подозреваю, что вы говорите о параллельной компьютерной панели инструментов; мне действительно все равно, если процесс займет много времени, но пока я запускаю этот код, я не могу использовать свой компьютер для других задач, это что-нибудь с этим делать? – user2751649

+0

Yep - вы можете использовать параллельный код, чтобы ускорить работу. Но если этот единственный процесс уже замедляет ваш/любой компьютер (или только один экземпляр Matlab-экземпляра?), То больше процессов, вероятно, еще больше ухудшит ситуацию ... – sebastian

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