7 Stimmen

Vorabzuweisung von Arrays in Matlab?

Ich verwende eine einfache for Schleife, um eine große Menge von Bildern zu beschneiden und sie dann in einem Zellenfeld zu speichern. Ich erhalte ständig die Meldung:

Die Variable croppedSag scheint die Größe bei jeder Schleifeniteration zu ändern. Erwägen Sie eine Vorabzuweisung für mehr Geschwindigkeit.

Ich habe dies schon mehrmals bei der Programmierung in MATLAB erlebt. Ich habe es immer ignoriert und bin neugierig, wie sehr die Vorabzuweisung die Laufzeit verlängert, wenn ich, sagen wir, 10.000 Bilder oder eine größere Anzahl habe?

Außerdem habe ich in der Dokumentation über die Vorabzuweisung gelesen, und dort heißt es, man solle zeros() zu diesem Zweck. Wie würde ich das für den unten stehenden Code verwenden?

croppedSag = {};
for i = 1:sagNum
    croppedSag{end+1} = imcrop(SagArray{i},rect);
end

Ich habe die Beispiele in der Dokumentation nicht ganz nachvollziehen können.

12voto

nibot Punkte 13820

Ein Array im Voraus zuzuweisen ist in Matlab immer eine gute Idee. Die Alternative ist, ein Array zu haben, das bei jeder Iteration durch eine Schleife wächst. Jedes Mal, wenn ein Element am Ende des Arrays hinzugefügt wird, muss Matlab ein völlig neues Array erzeugen, den Inhalt des alten Arrays in das neue Array kopieren und dann schließlich das neue Element am Ende hinzufügen. Durch die Vorabzuweisung entfällt die Notwendigkeit, ein neues Array zuzuweisen und Zeit damit zu verbringen, den vorhandenen Inhalt des Arrays in den neuen Speicher zu kopieren.

In Ihrem Fall ist der Nutzen jedoch nicht so groß, wie Sie vielleicht erwarten. Beim Kopieren des Zell-Arrays in ein neues, vergrößertes Zell-Array muss Matlab nicht unbedingt die Inhalt des Zellenfeldes (die Bilddaten), sondern nur Zeiger auf diese Daten.

Nichtsdestotrotz gibt es keinen Grund, eine Vorabzuweisung nicht vorzunehmen (es sei denn, Sie kennen die endgültige Größe nicht im Voraus). Hier ist eine vorab zugewiesene Version Ihrer Schleife:

croppedSag = cell(1, sagNum);
for ii = 1:sagNum
    croppedSag{ii} = imcrop(SagArray{ii}, rect);
end

Ich habe auch die Indexvariable "i" in "ii" geändert, damit sie die imaginäre Einheit nicht überschreibt.

Sie können diese Schleife auch mit der Funktion cellfun in einer Zeile neu schreiben:

croppedSag = cellfun(@(im) imcrop(im, rect), SagArray);

Hier ist ein Blogeintrag, der informativ sein könnte:

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X