Betrachten Sie die folgende Funktion:Unnötige Zuweisungen mit Julia Update Operatoren
function mytest(x, b)
y = zeros(x[:,:,1])
for i in 1:length(b)
y += b[i] * x[:,:,i]
end
return y
end
Wenn ich es laufen, erhalte ich folgendes:
x = rand(30,30,100000)
b = rand(100000)
@time mytest(x,b)
elapsed time: 0.571765222 seconds (727837732 bytes allocated, 66.49% gc time)
Warum ist es so viel Speicher und die Ausgaben so viel Zeit Zuteilung Garbage Collection machen? Der Code sollte type stable sein, und ich würde erwarten, dass der Operator +=
keine Neuzuweisung durchführt. Es scheint jedoch, dass es jedes Mal neu zugewiesen wird, wenn zwei Matrizen hinzugefügt werden.
Sollte ich das als Fehler in Julia betrachten? Und noch wichtiger, wie kann ich diesen Code so schreiben, dass er nicht neu zugeordnet wird?
EDIT: festen Tippfehler.
Die rechte Seite 'b [i] * x [:,:, i]' weist zuerst ein temporäres Array dem Ergebnis des Produkts zu, das vor Ort auf der linken Seite hinzugefügt wird. Das temporäre Array muss dann als Müll gesammelt werden. Zumindest ... so würde es mit [tag: numpy] funktionieren. –
@moarningsun, danke für den Tipp. Meine vorherige Erfahrung mit leistungskritischem Code verwendet hauptsächlich C++ und Eigen, die bei der Aufnahme eines Slices kein temporäres zuweisen würden. Ich habe meinen Code geändert, um drei verschachtelte for-Schleifen zu haben, und das Zuordnungsproblem wurde behoben. (Vorher habe ich versucht, das ArrayViews-Paket zu verwenden, aber das schien die Dinge nicht zu reparieren.) Ich bin immer noch neugierig, ob es einen besseren Weg gibt. –
@JimGarrison: Überprüfen Sie die Diskussion [hier] (https://groups.google.com/forum/#!topic/julia-users/i5hfGpWRHlk). '+ =' ist nur syntaktischer Zucker (für jetzt zumindest) und so denke ich, dass es immer nur neu zuweist (aber jemand korrigiert mich bitte, wenn ich falsch liege). Außerdem wäre ich daran interessiert zu sehen, wie die Three Loop Ihr Problem gelöst hat. – cd98