This is one of the input files.
How can I speed up my code?
3 次查看(过去 30 天)
显示 更早的评论
Hi! I wonder if it is possible to speed up my code. It's working properly and I have had plenty of help from your experts. So, a big thank you for that!
At the current data input (100 text files) it takes about 1 min and 7 sec to run.
Is it possible to make some adjustments to speed it up a bit? Here's my code and be please be kind I'm really a beginner at programming:
clear all
close all
addpath \\winfs...this is where I get my input textfiles...\months;
disp('Välkommen till detta verktyg för METAR-insamling!')
promt='Ange önskad flygplats ICAO-kod (ex ESSA):';
a=input(promt,'s');
disp('Data finns från 2008-07-01 00:20Z')
promt='Ange önskad starttid YYYYMM (ex 200807):';
b=input(promt,'s');
promt='Ange önskad sluttid YYYYMM (ex 201610):';
c=input(promt,'s');
disp('Bra val! Data laddas, detta kan ta upp till 1 min...')
formatIn = 'yyyymm';
Startnum=datenum(b,formatIn);
Slutnum=datenum(c,formatIn);
indata=[Startnum:Slutnum];
dvec=datevec(indata);
duniq = unique(dvec(:, 1:2), 'rows');
duniqyear = unique(duniq(:, 1), 'rows');
result = datenum(duniq(:,1), duniq(:,2), 1);
w=datestr(result,'yyyymm');
numfiles = length(w);
Data = cell(1, numfiles);
for h=1:numfiles;
filename=sprintf('%s.txt',w(h,:));
fileID=fopen(filename);
A=fread(fileID,'*char');
fclose(fileID);
B=A';
Data{h} = strread(B,'%s','delimiter','\n\b');
end
Utcell = cell(1,length(Data));
for l = 1:length(Data);
s = strfind(Data{l},a);
empty=zeros(1,length(Data{l}))';
j=0;
for k = 1:length(Data{l})
ind = find(s{k});
if ind==1;
empty(k)=j+1;
end
end
metar = find(empty);
Nydata = Data{l};
Utcell{l} = Nydata(metar);
end
Utmetar=cell(1,length(numfiles));
for n=1:length(w)
filename=sprintf('%s.txt',w(n,:));
YYYYMM = regexprep(filename, '.txt','');
flygplatsYYYYMM=Utcell{n};
yearmonth = YYYYMM;
Utmetar{n}=regexprep(flygplatsYYYYMM, '\d{6}Z', sprintf('%s$0', yearmonth));
end
disp('Var god vänta, sparar data som .xlsx-fil...')
UtmetarCell = {cat(1,Utmetar{:})};
UtmetarCat=UtmetarCell{:};
%XLSX-fil
delete('*.xlsx');
b=sprintf('%s.xlsx',a);
%xlswrite(b,UtmetarCat);
yearstring = regexp(UtmetarCat, '(?<= )\d{4}(?=\d+Z)', 'match', 'once'); %extract year as string
%assert(~any(cellfun(@isempty, yearstring)), 'Failed to find year in some string');
[duniqyear, ~, idx] = unique(str2double(yearstring)); %convert to numeric, get unique values and corresponding index in A
NaNduniqyear=isnan(duniqyear); %Letar efter NaN
Nanrows=length(find(NaNduniqyear)); %Hittar hur många NaNrader som finns
Asplit = accumarray(idx, 1:numel(UtmetarCat), [], @(indices) {UtmetarCat(indices)}); %distribute identical years in Dest
for f=1:length(duniqyear)-Nanrows
SaveMet=Asplit{f};
warning( 'off', 'MATLAB:xlswrite:AddSheet' ) ;
xlswrite(b,SaveMet,f)
end
disp('Klart!')
I suppose it's the multiple 'for loops' that takes up a lot of computing time. Any help is much appreciated!
10 个评论
采纳的回答
dbmn
2016-10-13
Just a few basic tips, there is tons of reading material available online on that topic
- The profiler is always a good idea to start. You can use it with the following code and it should help you identify the bottlenecks of your code.
profile on
% here comes your code (maybe without the clear all)
profile viewer
- Then you should try to avoid loops (especially stacked loops). Either by Vectorization or Matlab Built ins like arrayfun, cellfun, structfun etc.I assume that the following two statements can be replaced by a cellfun.
for l = 1:length(Data); %and
for k = 1:length(Data{l})
- You could avoid creating unnecessary variables like
SaveMet=Asplit{f};
xlswrite(b,SaveMet,f)
and simply use
xlswrite(b,Asplit{f},f)
- If it is still to slow, you could generate mex or c-code from your function
- more here: https://de.mathworks.com/company/newsletters/articles/accelerating-matlab-algorithms-and-applications.html
1 个评论
Guillaume
2016-10-13
编辑:Guillaume
2016-10-13
Yes, avoiding loop is a good idea (although matlab has improved in this respect, so may not be as critical). Vectorised operations can bring great speed up. However, it's unlikely that replacing a loop with cellfun, arrayfun and friends is going to make it faster. If anything due to the cost of extra function call (particularly if you use anonymous functions), it can actually be slower. However, you do gain in clarity and code quality (in my opinion).
Creating temporary variables should not be a problem, since until they are modified, they're just a pointer to the original variable.
更多回答(0 个)
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Loops and Conditional Statements 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!