Ich habe eine Funktion, deren Ausführung lange dauert. Wenn ich es profiliere, finde ich heraus, dass mehr als die Hälfte der Zeit (26 von 50 Sekunden) nicht in der zeilenweisen Zeitaufteilung berücksichtigt wird, und ich kann zeigen, dass die Zeit nach dem Ausführen der Funktion verbraucht wird, bevor sie die Kontrolle zurückgibt mit der folgenden Methode:
%Vor% Die erste Zeile der aufgerufenen Funktion ist ts2 = tic
und die letzte Zeile ist
Das Ergebnis ist
Aufruf der Funktion
letzte Zeile der Funktion - 24.0043
Steuerung kehrte zum Aufrufer - 49.857
zurück
Ich stochere in den Interwebs herum und denke, dass dies ein Symptom dafür ist, wie MATLAB das Gedächtnis verwaltet. Bei Funktionsrückgaben wird die Zuordnung aufgehoben, und manchmal dauert dies sehr lange. Die Funktion weist einige große (~ 1 Million Element) Arrays zu. Es funktioniert auch mit Handles, erstellt jedoch keine neuen Handle-Objekte oder speichert Handles explizit. Meine Fragen sind:
Ich habe eine Lösung für mein spezifisches Problem gefunden, die allgemein anwendbar ist.
Die Funktion, deren Exit lange dauerte, wurde für ein Basisobjekt aufgerufen, das einen Vektor von Handle-Objekten enthielt. Wenn ich die Definition des Basisobjekts in Extend-Handle änderte, eliminierte ich die Verzögerung beim Schließen der Funktion.
Was ich glaube, geschah: Wenn ich das Basisobjekt an meine Funktion übergeben habe, hat es eine Kopie dieses Objekts erstellt (MATLAB ist standardmäßig pass-by-value). Das dauert nicht viel Zeit, aber als die Funktion beendet wurde, zerstörte sie die Objektkopie, was dazu führte, dass sie durch den Vektor von Handle-Objekten guckte, um sicherzustellen, dass keine Waisen vorhanden waren, die bereinigt werden mussten. Ich glaube, dass diese Operation MATLAB lange Zeit in Anspruch nahm.
Wenn ich das Objekt änderte, das ich an ein Handle übergeben hatte, wurde im Funktionsarbeitsbereich keine Kopie erstellt, sodass am Ende keine Säuberung des Objekts erforderlich war.
Das deutet auf eine allgemeine Regel hin:
Wenn eine Funktion viel Zeit benötigt, um ihren Arbeitsbereich beim Beenden zu bereinigen, und Sie viele Daten oder komplexe Strukturen wertmäßig übergeben, versuchen Sie, die Argumente für diese Funktion in einem Handle-Objekt zu kapseln
Dadurch vermeiden Sie doppelte und damit zeitaufwendige Bereinigung beim Beenden. Der Nachteil ist, dass Ihre Funktion jetzt Ihre Eingaben unerwartet ändern kann, weil MATLAB nicht wie in C ++ ein Argument const deklarieren kann.
Sie haben recht, es scheint die Zeit zu sein, die Sie für Garbage Collection ausgegeben haben. Ich fürchte, es ist ein grundlegender MATLAB-Fehler, der seit Jahren bekannt ist, aber MathWorks hat ihn nicht einmal in der neuesten MATLAB-Version 2010b gelöst.
Sie könnten versuchen, Variablen manuell auf [] zu setzen, bevor Sie die Funktion verlassen - also die Garbage Collection manuell durchführen. Diese Technik hilft auch gegen Speicher Lecks in früheren MATLAB-Versionen. Jetzt wird MATLAB Zeit nicht auf end
, sondern auf myVar=[];
Sie könnten Probleme bei der Arbeit ohne jegliche Art von Referenzen lindern - anonyme Funktionen, verschachtelte Funktionen, Handle-Klassen, die nicht cellfun
und arrayfun
verwenden.
Wenn Sie an der "Leistungsbarriere" von MATLAB angekommen sind, sollten Sie vielleicht einfach die Umgebung ändern. Ich sehe sowieso keinen Sinn, wenn Sie heute ein neues Projekt in MATLAB starten, außer wenn Sie SIMULINK verwenden. Python Rocks für technisches Rechnen und mit C # können Sie auch viele Dinge tun, die MATLAB mit freien Bibliotheken macht. Und beide sind echte Programmiersprachen und sind im Gegensatz zu MATLAB frei.
Eine einfache Lösung könnte dies sein: Ordnen Sie die großen Arrays vorab zu und übergeben Sie sie als Argumente an Ihre FunktionCall (). Dadurch wird das Problem der Aufhebung der Zuordnung an den Aufrufer von functionCall () rückgängig gemacht. Es könnte jedoch sein, dass Sie functionCall häufiger aufrufen als das übergeordnete Element. In diesem Fall beschleunigt dies Ihren Code.
%Vor%Innerhalb von functionCall können Sie WorkArr initialisieren und / oder neu setzen, zum Beispiel
%Vor%Tags und Links garbage-collection matlab memory-management