Ich habe eine MATLAB-Routine mit einem offensichtlichen Engpass. Ich habe die Funktion profiliert, mit dem Ergebnis, dass in der Funktion levels
: 2/3 der Rechenzeit verwendet wird:
Die Funktion levels
verwendet eine Float-Matrix und teilt jede Spalte in nLevels
Buckets auf und gibt eine Matrix derselben Größe wie die Eingabe zurück, wobei jeder Eintrag durch die Nummer des Buckets ersetzt wird, in den er fällt.
Dazu benutze ich die Funktion quantile
, um die Bucket-Limits zu erhalten, und eine Schleife, um die Einträge den Buckets zuzuweisen. Hier ist meine Implementierung:
Gibt es etwas, was ich tun kann, um das zu beschleunigen? Kann der Code vektorisiert werden?
Wenn ich richtig verstehe, willst du wissen, wie viele Gegenstände in jedem Eimer gefallen sind. Verwenden Sie:
n = hist (Y, nbins)
Obwohl ich nicht sicher bin, dass es bei der Beschleunigung helfen wird. Es ist einfach sauberer.
Bearbeiten: Nach dem Kommentar:
Sie können den zweiten Ausgabeparameter von histc
verwenden[n, bin] = histc (...) gibt auch eine Indexmatrix zurück. Wenn x ein Vektor ist, ist n (k) = & gt; sum (bin == k). bin für Werte außerhalb des Bereichs null. Wenn x eine M-mal-N-Matrix ist, dann
Ich denke du solltest histc
[~,Y] = histc(X,q)
Wie Sie in Matlabs Dokument sehen können:
Beschreibung
n = histc (x, Kanten) zählt die Anzahl der fallenden Werte im Vektor x zwischen den Elementen im Kantenvektor (der enthalten muss monoton nicht abnehmende Werte). n ist ein Längen- (Kanten-) Vektor enthält diese Zählungen. Keine Elemente von x können komplex sein.
Ich habe ein paar Verfeinerungen (darunter eine von Aero Engy in einer anderen Antwort) gemacht, die zu einigen Verbesserungen geführt haben. Um sie zu testen, habe ich eine zufällige Matrix von einer Million Zeilen und 100 Spalten erstellt, um die verbesserten Funktionen auszuführen:
%Vor%Zuerst habe ich meinen unmodifizierten Code mit den folgenden Ergebnissen ausgeführt:
Beachten Sie, dass von den 40 Sekunden ungefähr 14 davon für die Berechnung der Quantile verwendet werden - ich kann nicht erwarten, diesen Teil der Routine zu verbessern (ich nehme an, dass Mathworks es bereits optimiert hat, obwohl ich vermute, dass es ein macht ...)
Als nächstes änderte ich die Routine auf die folgende, die schneller sein sollte und den Vorteil hat, weniger Linien zu sein!
%Vor%Die Profilergebnisse mit diesem Code lauten:
Es ist also 15 Sekunden schneller, was eine 150% ige Beschleunigung des Teils meines Codes und nicht von MathWorks bedeutet.
Nach einem Vorschlag von Andrey (wieder in einer anderen Antwort) habe ich den Code geändert, um die zweite Ausgabe der Funktion histc
zu verwenden, die den Bins Einträge zuweist. Es behandelt die Spalten nicht unabhängig voneinander, also musste ich die Spalten manuell durchlaufen, aber es scheint sehr gut zu funktionieren. Hier ist der Code:
Und die Profilergebnisse:
Wir geben jetzt nur 4,3 Sekunden in Codes außerhalb der Funktion quantile
aus, was eine Beschleunigung von 500% gegenüber dem ist, was ich ursprünglich geschrieben habe. Ich habe ein bisschen Zeit damit verbracht, diese Antwort zu schreiben, weil ich denke, dass es ein schönes Beispiel dafür ist, wie Sie den MATLAB-Profiler und StackExchange in Kombination verwenden können, um eine bessere Leistung Ihres Codes zu erzielen.
Ich bin glücklich mit diesem Ergebnis, obwohl ich natürlich weiterhin gerne andere Antworten hören werde. In diesem Stadium wird der Hauptleistungszuwachs durch die Erhöhung der Leistung des Teils des Codes erzielt, der momentan quantile
aufruft. Ich kann nicht sofort sehen, wie das geht, aber vielleicht kann jemand anderes hier. Nochmals vielen Dank!
Tags und Links optimization matlab vectorization bsxfun