Im Rahmen eines Projektes mussten wir uns mit einem System beschäftigen welches pro Artikel ca. 500 Attribute hat. Bestimmte Attribute sind bekanntermaßen für spezielle Anforderungen notwendig. Ein auslagern in eigene oxarticles Tabellenfelder kam aufgrund der Projektanforderungen nicht in Frage. Daher wurde etwas Aufwand in die Performance-Optimierung des Shops gesteckt. Speziell bei den Attributen.
Dabei kam die Frage auf, was schneller ist IF/ELSEIF oder SWITCH?
SPOILER-ALARM: Beide sind langsam, es gibt eine schnellere Lösung!
Aber nun erstmal der Test, ausgeführt auf PHP7.2, Ubuntu 18.04 LTS VM.
IF/ELSEIF
<?php
$i = 0;
while($i < 100000) {
$n = rand(0,9);
if($n == 0)
$i++;
elseif($n == 1)
$i++;
elseif($n == 2)
$i++;
elseif($n == 3)
$i++;
elseif($n == 4)
$i++;
elseif($n == 5)
$i++;
elseif($n == 6)
$i++;
elseif($n == 7)
$i++;
elseif($n == 8)
$i++;
elseif($n == 9)
$i++;
else
$i++;
}
?>
Switch
<?php
$i = 0;
while($i < 100000) {
$n = rand(0,9);
switch($n) {
case 0:
$i++;
break;
case 1:
$i++;
break;
case 2:
$i++;
break;
case 3:
$i++;
break;
case 4:
$i++;
break;
case 5:
$i++;
break;
case 6:
$i++;
break;
case 7:
$i++;
break;
case 8:
$i++;
break;
case 9:
$i++;
break;
default:
$i++;
}
}
?>
Das Ergebnis ist ernüchternd
Variante Laufzeit
If, ElseIf, Else 20.619163 ms
Switch 22.283724 ms
Eine Recherche und Diskussion auf Stack Overflow verwies auf ternäre Operatoren.
OK wagen wir einen Versuch.
<?php
$i = 0;
while($i < 100000) {
$n = rand(0,9);
($n == 0)?$i++:($n == 1)?$i++:($n == 2)?$i++:($n == 3)?$i++:($n == 4)?$i++:
($n == 5)?$i++:($n == 6)?$i++:($n == 7)?$i++:($n == 8)?$i++:($n == 9)?$i++:$i++;
}
?>
Ternäre Operatoren (?:) 4.873421 ms
WOW, das ist ein gewaltiger Unterschied. Performance auf Kosten der Lesbarkeit. Damit kann der geübte Entwickler leben. Aber wieso ist das so?
Relativ simpel. Die ternäre Operation ist ein Ausdruck, und wird nicht als Variable, sondern als Wert eines Ausdrucks ausgewertet. Das bedeutet keine direkte Zuweisung des Ergebnisses.