array_map vs Schleife und Operation

Lesezeit: 3 Minuten

Benutzer-Avatar
Eidechse

Verwendung:

for($i=1; $i<= 10000; ++$i) {
    $arrayOfNumbers[] = rand(1, 99999);
}

Kann jemand erklären, warum es so einen Geschwindigkeitsunterschied gibt:

array_map(array($maxHeap, 'insert'), $arrayOfNumbers);
# Avg Time: 0.92856907844543s

# against

foreach($arrayOfNumbers as $number) {
    $maxHeap->insert($number);
}
# Avg Time: 1.3148670101166

$maxHeap Objekt sein class MaxHeap extends SplMaxHeap

  • Wenn Sie ablehnen, geben Sie bitte einen Grund an!

    – Eidechse

    6. Dezember 2011 um 6:10 Uhr

  • Interessante Frage, soweit ich PHP’s kannte array_map() wurde intern vertreten als foreach – Korrigieren Sie mich bitte, wenn ich falsch liege.

    – Russel Dias

    6. Dezember 2011 um 6:17 Uhr

  • weil jede Funktion/Methode, die eingebaut ist, weniger Overhead für Opcode-Aufrufe hat, als es manuell zu tun. array_map ist eine eingebaute Methode, die das Array in C-Level und nicht in Opcode und dann in CPS behandelt, wie ich Ihre $arrayOfNumbers-Schleife sehe. Ich muss Ihnen das auch sagen: foreach ist schneller als while, while ist schneller als for. Wenn Sie es zum Iterieren eines Arrays verwenden, verwenden Sie foreach. Denn ist am langsamsten, weil es bei jeder Iteration 2 Prüfungen durchführt. Erstens, um die Endbedingung zu überprüfen, und zweitens macht es das ++$i. Also versuchen Sie es zu verwenden foreach(range(1,1000) as $i) stattdessen dafür und Benchmark dafür.

    – Dalibor Filus

    8. Dezember 2011 um 1:24 Uhr


  • pps Außerdem ist der Methodenaufruf in diesem zweiten foreach ein weiterer Overhead, der etwas über den Opcode macht. Objekte sind langsamer als Funktionen in fast jeder Sprache, einschließlich PHP. Tatsächlich erzeugen Sie dies (denken Sie in Opcode): [what is $arrayOfNumbers? lookup] Schleife:[get next array item in foreach][assign variable $number][$maxHeap? oh, I have to lookup that][is it object? can i call insert on it? raise exception if not][I’m calling it, with argument][put that argument to COW buffer][continue doing something else in insert][check for return value][nothing? good.][next loop if we can].

    – Dalibor Filus

    8. Dezember 2011 um 1:26 Uhr


Benutzer-Avatar
Jessie Ross

Meines Wissens macht PHP nichts asynchron, im Gegensatz zu Sajith Ammas Antwort.

Ich vermute, dass dies tatsächlich auf Unterschiede in der Suche zurückzuführen ist $maxHeap->insert.

Mit dem foreach Schleife, die Sie anrufen $maxHeap->insert innerhalb des aktuellen Geltungsbereichs muss der PHP-Interpreter nachschlagen maxHeap dann nachschauen insert auf der maxHeap Beispiel. Innerhalb des von Ihnen ausgeführten Skripts gibt es möglicherweise andere Variablen, die die Suche verlangsamen können.

Mit dem array_map Der PHP-Interpreter weiß, dass er genau dasselbe aufrufen wird $maxHeap->insertkann es die Suche nur einmal durchführen und dieselbe “Codeadresse” für die restlichen Iterationen verwenden.

Dies liegt an dem Unterschied zwischen Callback-Funktionen und normalen Funktionen.

In der zweiten Iteration des Arrays mit foreach ruft jede Iteration die Funktion “insert” auf und wartet auf die Ausführung (Funktionsrückgabesteuerung) und fährt mit der nächsten Iteration fort.

Aber in der Funktion array_map geschieht “insert” als Callback-Funktion, sie ruft “insert” auf und wartet nicht auf das Ergebnis und ruft insert mit dem nächsten Element im Array auf. Es geht also schneller.

Ich hoffe es hilft.

  • Ich frage mich, wie das wahr sein kann: array_map gibt ein Array dessen zurück, was der Callback zurückgegeben hat … Das ist das Verhalten von “map”.

    – Matthieu Napoli

    12. Oktober 2013 um 18:40 Uhr

  • Ich bezweifle auch stark, dass PHP die Aufrufe asynchron ausführt. -1 aufgrund des Fehlens einer guten Referenz.

    – Letharion

    26. Januar 2014 um 15:53 ​​Uhr

1217160cookie-checkarray_map vs Schleife und Operation

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy