Script esageratamente lento

di il
2 risposte

Script esageratamente lento

Salve a tutti mi presento, mi chiamo Rocco e sono uno studente di ingegneria prossimo alla laurea. E' il 26 dicembre e mi trovo su questo forum a cercare un aiuto perchè ho un problema e non so proprio come risolverlo, e se non dovessi riuscire a risolverlo non saprei veramente che pesci prendere. Ho creato un codice di matlab che mi permette di aprire in successione 512 file txt ed effettuare diverse operazioni algebriche su questi valori, per poi esportare un file xls che riassume il tutto. Il problema è che il run è veramente troppo lento, ci vorrebbero 49 ore per terminare il tutto (ed io questo codice lo dovrò usare in molte situazioni diverse). Secondo me ci sarà qualche conflitto che io non riesco a capire non essendo esperto in questo settore. Vi prego di aiutarmi, altrimenti dovrò effettuare migliaia e migliaia di volte queste operazioni a mano. Grazie a chi mi aiuterà!
P.S. Non riesco ad allegare il file txt col codice. Lo scrivo sotto.

intermedia=zeros(17520,35);
R=zeros(512,27);
v=zeros(512,2);
for i=1:512
T=importdata(strcat('COMPLETOA20KM',num2str(i),'.txt'));
C=T.data;
M=C(:,2:end);
intermedia(:,[1:4,6])=M(:,[1:4,6]);
intermedia(:,5)=M(:,2)+M(:,4);
intermedia(:,7:13)=M(:,7:13)/3.6;
intermedia(:,22:24) = M(:,14:16);
intermedia(:,25)=M(:,17)/3.6;
for k=1:8760 %for dell'anno
if intermedia(k,5)==0
intermedia(k,14)=0;
else
intermedia(k,14)=intermedia(k,2)/intermedia(k,5);
intermedia(k,15)=intermedia(k,4)/intermedia(k,5);
end
if intermedia(k,10)>0
intermedia(k,16)=intermedia(k,10).*intermedia(k,14);
intermedia(k,17)=intermedia(k,10).*intermedia(k,15);
intermedia(k,18)=intermedia(k,11).*intermedia(k,14);
intermedia(k,19)=intermedia(k,11).*intermedia(k,15);
intermedia(k,34)=intermedia(k,5); %verifica powerge (23, prima colonna)
intermedia(k,35)=intermedia(k,11)/(0.98*0.97)+intermedia(k,12)/0.98+intermedia(k,10)/0.98; %verifica powerge (seconda colonna)
%intermedia(k,32)=intermedia(k,11); %verifica power to load prima colonna

else
intermedia(k,16)=0;
intermedia(k,17)=0;
intermedia(k,18)=(intermedia(k,11)+intermedia(k,10)*0.97).*intermedia(k,14);
intermedia(k,19)=(intermedia(k,11)+intermedia(k,10)*0.97).*intermedia(k,15);
intermedia(k,34)=0; %powerge (prima colonna)
intermedia(k,35)=0; %powerge (seconda colonna)
%intermedia(k,32)=intermedia(k,10)*0.97*0.98-intermedia(k,11)*0.97; %verifica power to load prima colonna
end

intermedia(:,20)=intermedia(:,12).*intermedia(:,14);
intermedia(:,21)=intermedia(:,12).*intermedia(:,15);
intermedia(:,33)=intermedia(:,11)+intermedia(:,13); %verifica power to load seconda colonna
intermedia(:,26)= intermedia(:,22)./intermedia(:,25);
intermedia(:,27)= intermedia(:,23)./intermedia(:,25);
intermedia(:,28)= intermedia(:,24)./intermedia(:,25);
intermedia(:,29)= intermedia(:,26).*intermedia(:,11);
intermedia(:,30)= intermedia(:,27).*intermedia(:,11);
intermedia(:,31)= intermedia(:,28).*intermedia(:,11);
intermedia(:,32)=intermedia(:,25);

vp=abs(intermedia(:,34)-intermedia(:,35));
vl=abs(intermedia(:,32)-intermedia(:,33));
bvp=vp>0.5;
bvl=vl>0.5;
v(i,1)=sum(bvp);
v(i,2)=sum(bvl);

R(i,:)=0;
for j=1:8760
R(i,[1:5,8:27])=R(i,[1:5,8:27])+intermedia(j,[1:5,8,9,11:21,29:35]);
if intermedia(j,7)>0
R(i,6)=R(i,6)+intermedia(j,7);
else
R(i,7)=R(i,7)+intermedia(j,7);
end
end

R(i,:)=R(i,:)*10^-3;
end
end
xlswrite('verificaA20km.xlsx',v,1);
xlswrite('parametricresultsA20km.xlsx',R,1);

2 Risposte

  • Re: Script esageratamente lento

    Questo è un link di Mega dove poter scaricare alcuni dei file che importo in matlab con il codice e sui quali effettuo le operazioni.
  • Re: Script esageratamente lento

    Anche volendo considerare il processing di un singolo file di testo (e quindi ignorando il loop più esterno), il problema principale consiste nel fatto che il restante codice contiene due cicli for annidati ognuno da 8760 iterazioni il che vuol dire che, per ogni file di input il codice deve eseguire più di 76 milioni di iterazioni (8760*8760) e, se poi consideriamo il loop più esterno (quello sui 512 file di input), le iterazioni arrivano a quasi 40 miliadi! Decisamente tante.

    Premesso che non è facile (impossibile) capire quali operazioni vuoi eseguire sui dati di input, sembrano esserci alcune incongruenze nel codice che hai pubblicato.

    I file di testo sembrano avere tutti 17520 righe, ma i due loop interni "lavorano" solo sulle prime 8760 righe.
    Curiosamente 8760+8760 fa 17520 cioè il numero di righe dei file di input.

    Sei sicuro che i due loop interni debbano essere annidati e "consecutivi" in modo che, ad ogni iterazione (per ogni file di input) vengano elaborate tutte le righe?

    Un'altra incongruenza sembra rappresentata dal fatto che, dopo la serie di "if" del loop con indice "k",
    for k=1:8760 %for dell'anno
    c'è una serie di istruzioni come
    intermedia(:,20)=intermedia(:,12).*intermedia(:,14);
    intermedia(:,21)=intermedia(:,12).*intermedia(:,15);
    queste istruzioni non dipendono dalla variabile del ciclo "for", ma riguardano tutte le righe della matrice "intermedia" questo implica che ad ogni iterazione si ripetono uguali.
    In particolare. le prima due istruzioni utilizzano i valori nelle colonne "14" e "15" della k-esima riga della matrice "intermedia".
    La colonna 14 viene modificata nella sezione "if" che precede, ma la colonna "15" viene modificata solo nella sezione "else".

    Essendo i due loop interni annidati, il secondo, quello con indice "j"
     for j=1:8760
    opererà sempre su righe della matrice "intermedia" che non sono ancora state elaborate dal loop esterno (con indice "k") per cui ad ogni iterazione di questo ciclo, i precedente elaborati nel secondo loop, verranno sovrascritti.

    In conclusione, dovresti rivedere attentamente la struttura del codice che hai scritto e verificare le (apparenti) incongruenze.
Devi accedere o registrarti per scrivere nel forum
2 risposte