Verfasst am: 03.05.2012, 11:46
Titel: Finde den Fehler!
Hallo,
ich habe diese Funktion zwecks Verbesserung der Performance neugeschrieben:
Code:
function CalcPeriodAll_OLD(obj)
obj.PeriodAll=obj.ts(:,1);%Date column
obj.PeriodAll=[obj.PeriodAll,zeros(size(obj.PeriodAll,1),1)];%Expand the matrix
for i=1:size(obj.PeriodAll,1)
tmpDate=obj.PeriodAll(i,1)+1;
ifweekday(tmpDate)==7%Saturday
tmpDate=tmpDate+2;%Saturday->monday
elseifweekday(tmpDate)==1%Sunday
tmpDate=tmpDate+1;%Sunday->monday
end for m=1:size(obj.Holidays,1) if obj.Holidays(m)>tmpDate
break;%Exit loop
end if tmpDate==obj.Holidays(m)
tmpDate=tmpDate+1;
ifweekday(tmpDate)==7%Saturday
tmpDate=tmpDate+2;%Saturday->monday
elseifweekday(tmpDate)==1%Sunday
tmpDate=tmpDate+1;%Sunday->monday
end end end [~, tmpMonth, ~, ~, ~, ~] = datevec(tmpDate);
[~, ~, tmpDay, ~, ~, ~] = datevec(tmpDate);
if tmpDay<16
obj.PeriodAll(i,2)=tmpMonth*2-1;
else
obj.PeriodAll(i,2)=tmpMonth*2;
end end end
function CalcPeriodAll(obj)
obj.PeriodAll=[obj.ts(:,1),zeros(size(obj.ts,1),1)];%Inline: %Date column and expand matrix
for i=1:size(obj.PeriodAll,1)
tmpDate=obj.PeriodAll(i,1)+1;
ifweekday(tmpDate)==7%Saturday
tmpDate=tmpDate+2;%Saturday->monday
elseifweekday(tmpDate)==1%Sunday
tmpDate=tmpDate+1;%Sunday->monday
end [tf,~]=ismember(tmpDate,obj.Holidays);
iftf
tmpDate=tmpDate+1;
ifweekday(tmpDate)==7%Saturday
tmpDate=tmpDate+2;%Saturday->monday
elseifweekday(tmpDate)==1%Sunday
tmpDate=tmpDate+1;%Sunday->monday
end end [~, tmpMonth, tmpDay, ~, ~, ~] = datevec(tmpDate);
if tmpDay<16
obj.PeriodAll(i,2)=tmpMonth*2-1;
else
obj.PeriodAll(i,2)=tmpMonth*2;
end end end
im ersten Fall läuft die Schleife nach gefundenem Feiertag weiter.
Zum Beispiel Karfreitag wird Samstag, wird Ostermontag, wird Dienstag.
Inklusive eines etwas eleganteren Wochenend-Tests sähe das dann so aus:
Code:
WEEKENDSHIFT=[1,0,0,0,0,0,2]; % Samstag+Sonntag -> Montag
HOLYSHIFT=[1,1,1,1,1,3,2]; % mit Feiertag: ein Tag weiter, auszer Freitag+Samstag -> Montag [...]
tmpDate=tmpDate+WEEKENDSHIFT(weekday(tmpDate));
whileismember(tmpDate,obj.Holidays)
tmpDate=tmpDate+HOLYSHIFT(weekday(tmpDate));
end;
[...]
Wie meinst du das? Bei PeriodAll handelt es sich um einen nx2-double-Array.
Nein. Die Variable "PeriodAll" existiert gar nicht. Bisher existiert nur "obj.PeriodAll". Intern muss dies geschehen, um die Werte zu ändern:
1. Suche "obj" in der Variablen-Tabelle.
2. Finde den Pointer zur Liste der Feld-Namen.
3. Durchsuche die Feld-Namen Liste mit STRCMP bis das Feld "PeriodAll" gefunden wird.
4. Find den Pointer zu den dazugehörigen Feld.
5. Finde den Pointer zu den Daten des Feldes, also zum eigentliche Inhalt von "obj.PeriodAll".
Wenn man dagegen ein Double-Array verwendet, das nicht in einem Struct verschachtelt ist, merkt sich die JIT-Acceleration den Pointer zu den Daten direkt und die ganzen Suchereien entfallen. Deshalb ist es im Allgemeinen effizienter, ein temporäres Array zu verwenden, wenn ein Struct-Feld in einer Schleife häufig verändert wird.
Nein. Die Variable "PeriodAll" existiert gar nicht. Bisher existiert nur "obj.PeriodAll". Intern muss dies geschehen, um die Werte zu ändern:
1. Suche "obj" in der Variablen-Tabelle.
2. Finde den Pointer zur Liste der Feld-Namen.
3. Durchsuche die Feld-Namen Liste mit STRCMP bis das Feld "PeriodAll" gefunden wird.
4. Find den Pointer zu den dazugehörigen Feld.
5. Finde den Pointer zu den Daten des Feldes, also zum eigentliche Inhalt von "obj.PeriodAll".
Wenn man dagegen ein Double-Array verwendet, das nicht in einem Struct verschachtelt ist, merkt sich die JIT-Acceleration den Pointer zu den Daten direkt und die ganzen Suchereien entfallen. Deshalb ist es im Allgemeinen effizienter, ein temporäres Array zu verwenden, wenn ein Struct-Feld in einer Schleife häufig verändert wird.
Oh, ... na das muss man auch erstmal wissen!
Wenn ich jetzt z.B. die Werte von obj.PeriodAll(:,2) ändern möchte, werden tatsächlich die Schritte 1.-5. mit jeder Iteration durchgenudelt? "Merkt" sich Matlab nicht die Adresse von obj.PeriodAll bevor die for-Schleife durchlaufen wird?
Stimmt. Um Matlab wirklich effizient benutzen zu können, muss man zunächst wissen, wie der Code intern abgearbeitet wird. Dies steht allerdings nicht in der Dokumentation. Aber im Grunde unterscheiden sich Compiler nicht wesentlich, so dass eine Vorlesung Compiler-Bau und Erfahrung mit z.B. C-Compilern bereits einen tieferen Einblick erlauben.
Zitat:
Wenn ich jetzt z.B. die Werte von obj.PeriodAll(:,2) ändern möchte, werden tatsächlich die Schritte 1.-5. mit jeder Iteration durchgenudelt? "Merkt" sich Matlab nicht die Adresse von obj.PeriodAll bevor die for-Schleife durchlaufen wird?
Die JIT-Beschleunigung kann inzwischen einige Tricks. Ob Matlab ausnutzen kann, dass "obj.PeriodAll" ein statischer Pointer zu einem DOUBLE-Array ist, oder eben nicht, kannst Du am besten selbst ausprobieren. Setze ein TIC/TOC um den Code, lasse ihn am besten noch mehrfach durchlaufen, und schaue, was schneller ist.
Du kannst Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen. Du kannst Dateien in diesem Forum posten Du kannst Dateien in diesem Forum herunterladen
MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.