Verfasst am: 10.05.2012, 17:08
Titel: libpointer zu langsam
Hallo,
Code:
%% Moving STDEV -- adjusted standard deviation function CalcMovingSTDEV(obj) ifisempty(obj.Performance)==1
CalcPerformance(obj);
end
obj.mSTDEV=obj.ts(:,1);%Date column
for j=1:size(obj.mSTDEV_Indicator,1) if obj.mSTDEV_Indicator(j,1)==0
x=libpointer('doublePtr',obj.Performance(:,obj.mSTDEV_Indicator(j,2)));
else
x=libpointer('doublePtr',obj.ts(:,obj.mSTDEV_Indicator(j,2)));
end
obj.mSTDEV=[obj.mSTDEV,zeros(size(x.value,1),1)];%Expand the matrix
for i=1:size(x.value,1)-obj.mSTDEV_Indicator(j,3)
obj.mSTDEV(i,j+1)=std(x.value(i:i+obj.mSTDEV_Indicator(j,3)-1));
end if obj.mSTDEV_Indicator(j,4) ~= 1 for i=1:size(x.value,1)-obj.mSTDEV_Indicator(j,3)
obj.mSTDEV(i,j+1)=obj.mSTDEV(i,j+1)*sqrt(obj.mSTDEV_Indicator(j,4));%Annualized Vola
end end for i=size(x.value,1)-obj.mSTDEV_Indicator(j,3)+1:size(x.value,1)
obj.mSTDEV(i,j+1)=NaN;
end end end
libpointer wie im obigen code benutze ich zuhauf in meinen Funktionen. Ich finde dies ist eine elegante Methode diverse if-Abfragen zu umgehen und trägt somit wesentlich zu Lesbarkeit des codes bei. Leider sind die libpointer auch sehr langsam! Woran liegt das, Matlab greift doch direkt auf den Speicherplatz des referenzierten Objektes zu?
Gibt es eine ähnliche Hernangehensweise, d. h. code-Redundanzen vermeiden mit hoher performance???
Verfasst am: 13.05.2012, 01:10
Titel: Re: libpointer zu langsam
Hallo Lloyd Blankfein,
Der Code hat noch hinreichend viel anderes Beschleunigungspotential, so dass ich libpointer erstmal hinten anstellen würde.
Z.B. ist der immer wieder wiederholte Zugriff auf "obj.mSTDEV_Indicator(j,3)" zeitraubend.
Auch "sqrt(obj.mSTDEV_Indicator(j,4)" muss man nicht in jeder Iteration der "for i"-Schlweife neu berechnen.
Das Schreiben in ein Struct-Feld dauert länger als direkt in ein Double-Array zu schreiben, da das Referenzieren des Feldes Zeit benötigt. Ich dachte, das hätte ich in einem früheren Thread umfassend erklärt.
Das wiederholte Vergrößern einer Matrix ist ebenfalls zeitraubend. Besser wäre es, gleich die entgültige Größe des Arrays zu allozieren.
Code:
function CalcMovingSTDEV(obj) ifisempty(obj.Performance)==1
CalcPerformance(obj);
end
Q = obj.mSTDEV_Indicator;
M = obj.ts(:,1);%Date column
M(1, size(Q, 1) + 1) = 0; % Appens a ZERO matrix automatically
for j=1:size(Q, 1) if Q(j,1)==0
x=libpointer('doublePtr',obj.Performance(:, Q(j,2)));
else
x=libpointer('doublePtr',obj.ts(:, Q(j,2)));
end
sx = size(x, 1);
Qj3 = Q(j, 3);
jp1 = j + 1;
xv = x.value;
for i=1:sx-Qj3
M(i,jp1) = sqrt(var(xv(i:i + Qj3 -1))); % SQRT(VAR()) is faster than STD() end if Q(j,4) ~= 1
M(1:sx - Qj3, jp1) = M(1:sx - Qj3,jp1) * sqrt(Q(j,4));
end
M(sx - Qj3 + 1:sx, jp1) = NaN;
end
obj.mSTDEV = M;
end
Da mir die Definition von "obj" immer noch nicht klar ist könnten unbekannte Seiten-Effekte beim Zugriff auf "obj.mSTDEV" vorhanden sein. Das müsstest Du also noch selbst debuggen. Ich finde es optisch jedenfalls einfacher.
Du kannst Dir die Definition von VAR anschauen. Es wird für jeden Teil-Vektor zunächst der Mittelwert berechnet. Dies läßt sich aber vereinfachen, weil ja immer nur ein neues Element angefügt und eines abgezogen wird.
In Matlab wird das nicht viel bringen, aber als C-Mex wäre wohl eine doppelte Geschwindigkeit machbar.
Das wird aber nicht hilfreich sein, wenn Du zunächst Stunden verwendest, um ein C-Mex zu schreiben, nur um Sekunden zu sparen.
Gruß, Jan
Einstellungen und Berechtigungen
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.