Bei meinen Tests habe ich festgestellt, dass das Iterieren über verknüpfte Arrays bestenfalls halb so schnell ist wie die Verwendung der internen Zugriffsmethoden ( FETCH
und FETCHSIZE
). Der folgende Benchmark zeigt das Problem:
Bei einer Array-Größe von 1000 gibt der Benchmark Folgendes aus:
%Vor%Ich habe die anderen Läufe weggelassen, weil die Größe des Arrays keine sinnvolle Änderung der relativen Geschwindigkeiten bewirkt.
method
ist natürlich am schnellsten, weil es nicht die Größe des Arrays bei jeder Iteration überprüft, aber method_while
und method_while2
scheinen auf der gleichen Weise wie das% co_de auf dem gebundenen Array zu operieren % loop, aber selbst das langsamere for
ist doppelt so schnell wie das verbundene Array.
Sogar das Hinzufügen der Lokalisierung von method_while2
und Alias-Zuweisung zu $_
in method_while2
führt zu 66% schnellerer Ausführung als das verbundene Array.
Welche zusätzliche Arbeit wird in der method_while3
-Schleife ausgeführt, die nicht in for
stattfindet? Gibt es eine Möglichkeit, die Geschwindigkeit des gebundenen Arrays zu verbessern?
Im Benchmark tun Sie
%Vor%Was wäre, wenn Sie es getan hätten
? %Vor%Es würde funktionieren. Bindungs-Magie umschließt den von FETCH zurückgegebenen Wert in einen L-Wert, wenn der Wert im Lvalue-Kontext zurückgegeben wird. Sie können dies mit Devel :: Peek sehen.
%Vor%Den von FETCH zurückgegebenen Wert in ein magisches SV zu packen und die Magie zu verarbeiten, macht zumindest einen Teil des Unterschieds aus.
%Vor%Jedes Mal, wenn Sie das gebundene Array verwenden, muss es das gebundene Objekt nachschlagen, dann die Methoden nachschlagen und sie dann aufrufen. Mit Ihren anderen Versionen machen Sie einen Teil oder die gesamte Suche entweder zur Kompilierzeit oder einmal vor der Schleife und nicht bei jedem Zugriff.
(Der Vergleich der Geschwindigkeiten zwischen method
und den anderen method_*
-Versionen ist übrigens ein gutes Beispiel dafür: Sie sehen die Kosten dafür, FETCHSIZE
zu machen, sogar wenn das gebundene Objekt bereits gesehen wurde up. Wenden Sie diese Kosten nun auf jede einzelne Operation an, die das Array berührt.)
Es ist erwähnenswert, dass local
sehr langsam ist, was einen Teil des Leistungsverlusts in method_while3 gegenüber den anderen Methoden-Benchmarks ausmacht. Es macht auch eine Block-Ein- und Ausfahrt, die Kosten hat.
Obwohl method_while3
programmatisch äquivalent zu statement for x..y
ist, kann Perl die for-Schleife besser optimieren als Sie. Als Faustregel gilt, je mehr Code Sie in Perl ausführen, desto schneller wird Ihr Code sein.
Tags und Links perl performance