Was ist schneller in PHP, eine große Switch-Anweisung oder ein Array-Key-Lookup, bei dem die Array-Initialisierung jedes Mal bezahlt wird?

Lesezeit: 5 Minuten

Benutzer-Avatar
Ariel

Was ist schneller in PHP, eine große switch-Anweisung zu machen oder ein Array einzurichten und den Schlüssel nachzuschlagen?

Bevor Sie jetzt antworten, ist mir bewusst, dass das Array für reine Suchen schneller ist. Dies setzt jedoch voraus, dass das Array nur einmal erstellt und dann wiederholt nachgeschlagen wird.

Aber das mache ich nicht – jeder Durchlauf des Codes ist neu, und das Array wird verwendet nur einmal jedes Mal. Daher müssen alle Array-Hashes jedes Mal neu berechnet werden, und ich frage mich, ob diese Einrichtung langsamer ist als einfach eine switch Aussage.

  • Versuch es. Schreiben Sie ein PHP-Skript, um jede Methode einige 100.000 Mal auszuführen, und geben Sie die Dauer für jede der beiden Methoden aus. Diese Art von Optimierungen machen auf lange Sicht jedoch selten einen signifikanten Unterschied.

    – Rich Adams

    27. Juli 2011 um 23:59 Uhr


  • “Spielt es überhaupt eine Rolle”? Wenn es dann keine Leistungsanalyse gegeben hat – nein, tut es nicht. Verwenden Sie, was übersichtlicher und wartbarer ist. (Es kann keines der oben genannten sein).

    Benutzer166390

    28. Juli 2011 um 0:00 Uhr


  • Diese Leistungsoptimierungen werden auf lange Sicht wahrscheinlich nicht viele Ergebnisse bringen, vielleicht ein paar Millisekunden oder so. Wenn Sie dies tatsächlich in einer groß angelegten Umgebung bereitstellen, werden diese Optimierungen aufgrund der Rechenleistung, die Sie erhalten, wahrscheinlich vernachlässigbar sein. Allerdings nur meine Meinung. Probieren Sie es aus und sehen Sie. Führen Sie einen Stresstest durch. Experimentieren ist der Weg, um die Antwort zu bekommen 🙂

    – Jimmie Lin

    28. Juli 2011 um 0:15 Uhr

  • Ich habe keine Leistungsanalyse versucht, aber ich würde annehmen, dass die Mikrooptimierung darin bestehen würde, die Hashes zu speichern, damit die Hashes nicht jedes Mal neu berechnet werden müssen.

    – Erinnerung

    28. Juli 2011 um 0:20 Uhr

  • @jared-farrish Ich könnte meinen Code auf zwei Arten erstellen, also würde ich wählen, was schneller ist. (Zumindest wenn es einen großen Unterschied gab.)

    – Arielle

    28. Juli 2011 um 0:28 Uhr

Benutzer-Avatar
Ariel

Ich habe einige Tests gemacht:

Datei array_gen.php

<?
    echo '<?
        $a = 432;
        $hash = array(
    ';

    for($i = 0; $i < 10000; $i++)
        echo "$i => $i,\n";

    echo ');
        echo $hash[$a];
    ';

Datei switch_gen.php:

<?
    echo '<?
        $a = 432;
        switch($a) {
    ';
    for($i = 0; $i < 10000; $i++)
        echo "case $i: echo $i; break;\n";

    echo '}';

Dann:

php array_gen.php > array_.php
php switch_gen.php > switch.php

time tcsh -c 'repeat 1000 php array.php > /dev/null'
19.297u 4.791s 0:25.16 95.7%
time tcsh -c 'repeat 1000 php switch.php > /dev/null'
25.081u 5.543s 0:31.66 96.7%

Dann habe ich die Schleife geändert zu:

for($i = 'a'; $i < 'z'; $i++)
  for($j = 'a'; $j < 'z'; $j++)
    for($k = 'a'; $k < 'z'; $k++)

Um 17576 zu erstellen, 3 Buchstabenkombinationen.

time tcsh -c 'repeat 1000 php array.php > /dev/null'
30.916u 5.831s 0:37.85 97.0%
time tcsh -c 'repeat 1000 php switch.php > /dev/null'
36.257u 6.624s 0:43.96 97.5%

Die Array-Methode gewinnt jedes Mal, selbst wenn Sie die Einrichtungszeit einbeziehen. Aber nicht viel. Ich denke also, ich werde diese Optimierung ignorieren und mich für das entscheiden, was einfacher ist.

  • 6 Sekunden Unterschied für 10.000 Iterationen. Das ist also ein Gewinn von 0,0006 für eine Iteration. Verwenden Sie, was einfacher zu programmieren ist. Das ist fast Übrigens immer das Richtige, da bessere Hardware fast immer billiger ist als die Zeit, die Sie für die Optimierung von Dingen aufwenden (was den Code normalerweise weniger lesbar macht == weniger wartbar == mehr Arbeit, um ihn zu ändern == sogar mehr Optimierungskosten).

    – Martin Tournij

    31. Juli 2011 um 8:25 Uhr

  • @ Ariel, -1. Welche PHP-Engine (Version)? Welches Betriebssystem? Wenn du Tests machen willst, mach sie ausführlich. Die Ergebnisse halbherziger Tests sind schädlich. Man kann ihnen nicht trauen und ihre Schlussfolgerung sollte mit einem riesigen Körnchen Salz aufgenommen werden. Die Frage ist noch offen.

    – Schrittmacher

    5. März 2015 um 19:29 Uhr


  • Was sind die vier Spalten in der Ausgabe von time und was sind einheiten? Sie entsprechen nicht die Manpage ((i) die verstrichene Echtzeit, (ii) die Benutzer-CPU-Zeit und (iii) die System-CPU-Zeit). Welche der vier Spalten sind sinnvoll zum Vergleichen und warum?

    – Peter Mortensen

    2. Februar 2020 um 21:41 Uhr


  • @PeterMortensen Sie sind Benutzer-CPU-Zeit, System-CPU-Zeit, verstrichene Zeit, Prozentsatz der verwendeten CPU. Verwenden Sie zum Vergleichen entweder die erste Spalte oder die zweite Spalte.

    – Arielle

    3. Februar 2020 um 0:15 Uhr

Es hängt irgendwie von der Arraygröße ab, aber für die meisten praktischen Zwecke können Sie davon ausgehen, dass das Array schneller ist. Der Grund ist einfach; eine switch-Anweisung muss sequenziell mit jedem Eintrag in der switch-Anweisung vergleichen, aber der Array-Ansatz nimmt einfach den Hash und findet diesen Eintrag. Wenn Sie so wenige Einträge in Ihrem Switch haben, dass die sequentiellen Vergleiche schneller sind als das Hashing, ist es schneller, einen Switch zu verwenden, aber der Array-Ansatz wird schnell effizienter. In der Informatik geht es um O(n) vs. O(1).

  • Meine Frage bezog sich auch auf die Geschwindigkeit, mit der das Array überhaupt erstellt wird, da das Array nur einmal verwendet wird.

    – Arielle

    28. Juli 2011 um 0:11 Uhr


  • @Ariel: ja, das verstehe ich; die Array-Erstellung beinhaltet das Hashen des Schlüssels, der in das Array eingefügt werden soll; der Hash zum Einfügen des Schlüssels und der Hash zum Suchen eines Schlüssels sind beide O(1).

    – Paul Sonier

    28. Juli 2011 um 4:18 Uhr

  • Der Hash zum Einfügen des Schlüssels ist O(n), nicht O(1), da Sie alle einfügen müssen, bevor Sie nachschlagen können. Aber der Schalter (im Durchschnitt) ist O(n/2).

    – Arielle

    28. Juli 2011 um 6:00 Uhr

  • @PaulSonier, Warum muss eine switch-Anweisung sequentiell verglichen werden? Dass kann das sein, was die Implementierung der Zend-Engine gerade tut, aber es gibt keine solche theoretische Einschränkung, und in Zukunft könnte es gut sein, dass sie es tun nicht nacheinander vergleichen.

    – Schrittmacher

    5. März 2015 um 19:17 Uhr

  • @ Pacerier, nun, das wäre nicht einfach, ohne BC zu brechen. Es gibt auch diese seltsame switch(TRUE)-Syntax, die davon ausgeht, dass sie sequentiell aufgerufen wird (switch(TRUE) { case ($a == $b): return 1; case ($a == 0): return 2; })

    – Giraffe

    1. September 2016 um 17:03 Uhr

1054190cookie-checkWas ist schneller in PHP, eine große Switch-Anweisung oder ein Array-Key-Lookup, bei dem die Array-Initialisierung jedes Mal bezahlt wird?

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

Privacy policy