In Perl, warum sind verknüpfte Arrays so langsam?

8

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:

%Vor%

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?

    
Eric Strom 01.04.2011, 19:58
quelle

3 Antworten

3

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%     
ikegami 03.04.2011, 04:47
quelle
7

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.)

    
geekosaur 01.04.2011 20:02
quelle
3

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.

    
Schwern 04.04.2011 04:16
quelle

Tags und Links