Leistung von foreach, array_map mit lambda und array_map mit statischer Funktion
Was ist der performance-Unterschied (falls es welche gibt) zwischen diesen drei Ansätzen, die beide zum umwandeln eines Arrays einem anderen array?
- Mit
foreach
- Mit
array_map
mit lambda/closure-Funktion - Mit
array_map
mit 'static' - Funktion/- Methode - Gibt es einen anderen Ansatz?
Machen mir klar, wir haben Blick auf die Beispiele, die alle das gleiche tun - die Multiplikation des array von zahlen von 10:
$numbers = range(0, 1000);
Foreach
$result = array();
foreach ($numbers as $number) {
$result[] = $number * 10;
}
return $result;
Map mit lambda
return array_map(function($number) {
return $number * 10;
}, $numbers);
Karte mit 'static' - Funktion als string übergeben Referenz
function tenTimes($number) {
return $number * 10;
}
return array_map('tenTimes', $numbers);
Gibt es einen anderen Ansatz? Ich werde glücklich sein, zu hören, eigentlich alle Unterschiede zwischen den Fällen von oben, und alle Eingänge, warum sollte man statt des anderen.
Warum gehst du nicht einfach benchmark, und sehen, was passiert?
Gut, ich kann einen benchmark. Aber ich weiß immer noch nicht, wie es intern funktioniert. Auch wenn ich finden Sie heraus, ist schneller, ich weiß immer noch nicht, warum. Ist es, weil der PHP-version? Kommt es auf die Daten? Gibt es einen Unterschied zwischen assoziativen und gewöhnliche arrays? Kann ich natürlich machen ganze suite von benchmarks aber immer einige Theorie spart hier eine Menge Zeit. Ich hoffe, Sie verstehen...
Verspäteter Kommentar, aber nicht while( list($k, $v)= each($array)) schneller als alle der oben genannten? Ich habe nicht gemessen, dieses in php5.6 aber es war in früheren Versionen.
Gut, ich kann einen benchmark. Aber ich weiß immer noch nicht, wie es intern funktioniert. Auch wenn ich finden Sie heraus, ist schneller, ich weiß immer noch nicht, warum. Ist es, weil der PHP-version? Kommt es auf die Daten? Gibt es einen Unterschied zwischen assoziativen und gewöhnliche arrays? Kann ich natürlich machen ganze suite von benchmarks aber immer einige Theorie spart hier eine Menge Zeit. Ich hoffe, Sie verstehen...
Verspäteter Kommentar, aber nicht while( list($k, $v)= each($array)) schneller als alle der oben genannten? Ich habe nicht gemessen, dieses in php5.6 aber es war in früheren Versionen.
InformationsquelleAutor Pavel S. | 2013-08-09
Du musst angemeldet sein, um einen Kommentar abzugeben.
FWIW, ich habe gerade die benchmark, da die poster nicht. Läuft auf PHP 5.3.10 + XDebug.
UPDATE 2015-01-22 vergleichen mit mcfedr Antwort unten für weitere Ergebnisse, ohne XDebug und eine neuere PHP-version.
Ich bekomme ziemlich konsistente Ergebnisse mit 1M zahlen über ein Dutzend versuche:
Angenommen, dass der mäßigen Geschwindigkeit der Karte auf Schließung wurde verursacht durch die Schließung möglicherweise ausgewertet werden jedes mal, habe ich auch getestet, wie diese:
Aber die Ergebnisse sind identisch, die bestätigt, dass die Schließung wird nur einmal ausgewertet.
2014-02-02-UPDATE: opcodes dump
Hier sind die opcode-dumps für die drei Rückrufe. Erste
useForeach()
:Dann die
useMapClosure()
sowie die Schließung ruft es:
dann die
useMapNamed()
Funktion:und die angegebene Funktion ruft es,
_tenTimes()
:Ich habe den opcode steckt in der Frage. Erste, was wir sehen können ist, dass der benannte Funktion und Verschluss sind genau die gleichen dump, und Sie sind aufgerufen, per array_map in viel die gleiche Weise, mit nur einer Ausnahme: der closure-Aufruf enthält eine weitere opcode DECLARE_LAMBDA_FUNCTION, die erklärt, warum es ist ein bisschen langsamer als die benannte Funktion. Nun, der Vergleich der array-Schleife array_map vs fordert, alles, was in der array-Schleife interpretiert, inline, ohne Aufruf einer Funktion, was bedeutet, kein Zusammenhang von push/pop, nur einen JMP am Ende der Schleife, die wahrscheinlich erklärt den großen Unterschied.
Ich habe gerade versucht dies mit einer built-in-Funktion (strtolower), und in diesem Fall
useMapNamed
ist tatsächlich schneller alsuseArray
. Dachte, das war erwähnenswert.In
lap
, wollen Sie nicht dierange()
Anruf über die erste microtime nennen? (Obwohl wahrscheinlich unbedeutend im Vergleich mit der Zeit für die Schleife.)PHP7.x ist so viel schneller, in der Tat. Es wäre interessant zu sehen, die opcodes generiert diese version, vor allem den Vergleich mit/ohne opcache, da es eine Menge an Optimierungen neben code-caching.
InformationsquelleAutor FGM
Seine interessante, die zur Ausführung dieser benchmark mit xdebug deaktiviert, da xdebug fügt sehr viel Aufwand, esp-Funktion aufruft.
Dies ist FGM ' s Skript ausführen, verwenden 5.6
Mit xdebug
Ohne xdebug
Hier gibt es nur einen sehr kleinen Unterschied zwischen foreach und Verschluss-version.
Es ist auch interessant zu fügen, eine version mit einem Verschluss mit einem
use
Zum Vergleich füge ich hinzu:
Hier können wir sehen, es macht einen Einfluss auf die Verschluss-version, in der Erwägung, dass der array noch nicht merklich verändert.
19/11/2015 habe ich jetzt auch Hinzugefügt, Ergebnisse mit PHP 7 und HHVM für den Vergleich. Die Schlussfolgerungen sind ähnlich, obwohl alles viel schneller.
Ich erkläre Euch zum Sieger durch das brechen der Band und geben Sie die 51st upvote. SEHR wichtig, um sicherzustellen, dass der test keinen Einfluss auf die Ergebnisse! Frage, obwohl, dein Ergebnis mal nach "Array" sind die foreach-loop-Methode, richtigen?
Ausgezeichnete Antwort. Schön zu sehen, wie schnell 7 ist. Gotta beginnen, es auf meine persönliche Zeit, die noch am 5.6 bei der Arbeit.
array_map
(und die zugehörigen Funktionenarray_reduce
,array_filter
) lassen Sie schreiben, schönen code. Wennarray_map
war viel langsamer wäre es ein Grund für die Verwendungforeach
, aber seine sehr ähnlich, also werde icharray_map
überall dort, wo es Sinn macht.Schön zu sehen, PHP7 erheblich verbessert. War etwa der Wechsel zu einem anderen backend-Sprache für meine Projekte, aber ich werde den stick zu PHP.
InformationsquelleAutor mcfedr
Ist es interessant. Aber ich habe ein gegenteiliges Ergebnis mit den folgenden codes, die vereinfacht aus meiner aktuellen Projekte:
Hier ist mein Test-Daten und codes:
Ist das Ergebnis:
Meine tests waren in der LAMPE Produktionsumgebung ohne xdebug.
Ich bin wandernden xdebug verlangsamen würde array_map Leistung.
array_map
😉Ich habe testen der Leistung von
array_map
undforeach
mit Xhprof. Und Seine interessantearray_map
verbraucht mehr Speicher als ` foreach`.InformationsquelleAutor Clarence