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.