Was ist der Leistungsunterschied (falls vorhanden) zwischen diesen drei Ansätzen, die beide zum Transformieren eines Arrays in ein anderes Array verwendet werden?
- Verwenden von
foreach
- Verwendung
array_map
mit Lambda / Verschlussfunktion - Verwendung
array_map
mit 'statischer' Funktion / Methode - Gibt es einen anderen Ansatz?
Um mich klar zu machen, schauen wir uns die Beispiele an, die alle dasselbe tun - multiplizieren Sie das Zahlenfeld mit 10:
$numbers = range(0, 1000);
Für jedes
$result = array();
foreach ($numbers as $number) {
$result[] = $number * 10;
}
return $result;
Karte mit Lambda
return array_map(function($number) {
return $number * 10;
}, $numbers);
Map mit 'statischer' Funktion, übergeben als String-Referenz
function tenTimes($number) {
return $number * 10;
}
return array_map('tenTimes', $numbers);
Gibt es einen anderen Ansatz? Ich werde mich freuen, tatsächlich alle Unterschiede zwischen den Fällen von oben und alle Eingaben zu hören, warum einer anstelle anderer verwendet werden sollte.
Antworten:
FWIW, ich habe gerade den Benchmark gemacht, da das Poster es nicht gemacht hat. Läuft unter PHP 5.3.10 + XDebug.
UPDATE 22.01.2015 Vergleiche mit der Antwort von mcfedr unten, um zusätzliche Ergebnisse ohne XDebug und eine neuere PHP-Version zu erhalten.
Ich erhalte ziemlich konsistente Ergebnisse mit 1 Million Zahlen über ein Dutzend Versuche:
Angenommen, die glanzlose Geschwindigkeit der Karte beim Schließen wurde dadurch verursacht, dass der Abschluss möglicherweise jedes Mal ausgewertet wird, habe ich auch Folgendes getestet:
Die Ergebnisse sind jedoch identisch, was bestätigt, dass der Verschluss nur einmal ausgewertet wird.
2014-02-02 UPDATE: Opcodes-Dump
Hier sind die Opcode-Dumps für die drei Rückrufe. Erstens
useForeach()
:Dann ist die
useMapClosure()
und die Schließung, die es nennt:
dann die
useMapNamed()
Funktion:und die benannte Funktion, die es aufruft ,
_tenTimes()
:quelle
useMapNamed
tatsächlich schneller alsuseArray
. Ich dachte, das wäre erwähnenswert.lap
, wollen nicht , dass Sie denrange()
Anruf über dem ersten micro Anruf? (Obwohl wahrscheinlich unbedeutend im Vergleich zur Zeit für die Schleife.)Es ist interessant, diesen Benchmark mit deaktiviertem xdebug auszuführen, da xdebug viel Aufwand verursacht, insbesondere bei Funktionsaufrufen.
Dies ist das Skript von FGM, das mit 5.6 With xdebug ausgeführt wird
Ohne xdebug
Hier gibt es nur einen sehr kleinen Unterschied zwischen der Foreach- und der Closure-Version.
Es ist auch interessant, eine Version mit einem Verschluss mit einem hinzuzufügen
use
Zum Vergleich füge ich hinzu:
Hier können wir sehen, dass es sich auf die Abschlussversion auswirkt, während sich das Array nicht merklich geändert hat.
19/11/2015 Ich habe jetzt auch Ergebnisse mit PHP 7 und HHVM zum Vergleich hinzugefügt. Die Schlussfolgerungen sind ähnlich, obwohl alles viel schneller ist.
quelle
array_map
(und die damit verbundene Funktionenarray_reduce
,array_filter
) können Sie schönen Code schreiben. Wennarray_map
es viel langsamer wäre, wäre es ein Grund, es zu verwendenforeach
, aber es ist sehr ähnlich, also werde ich esarray_map
überall verwenden, wo es Sinn macht.Es ist interessant. Aber ich habe ein gegenteiliges Ergebnis mit den folgenden Codes, die aus meinen aktuellen Projekten vereinfacht wurden:
Hier sind meine Testdaten und Codes:
Das Ergebnis ist:
Meine Tests wurden in einer LAMP-Produktionsumgebung ohne xdebug durchgeführt. Ich wandere durch xdebug, was die Leistung von array_map verlangsamen würde.
quelle
array_map
;)array_map
undforeach
mit Xhprof. Und sein interessantesarray_map
verbraucht mehr Speicher als "foreach".