„$var === null“ vs. „is_null($var)“
Vor etwa zwei Wochen hat Zend das Zend Framework 1.10.8 Released. Ein interessanter Eintrag aus dem Changelog ist, dass alle is_null durch === null ersetzt wurden.
Das hat mich interessiert und ich habe mal nachgeschaut warum dies geschehen ist, weil ich der Meinung war soviel Unterschied macht das eh nicht.
Hier mal der Beispielcode für einen Benchmark aus dem entsprechenden Issue:
echo '"is_null($var)" vs. "$var === null"' . "\n"; $max = 100000; $varNull = null; $varNotNull = true; echo ' is_null($var): '; $start = microtime(true); for ($i = 0; $i < $max; $i++) { is_null($varNull); is_null($varNotNull); } $end = microtime(true); echo($end - $start) . "\n"; echo ' $var === null: '; $start = microtime(true); for ($i = 0; $i < $max; $i++) { ($varNull === null); ($varNotNull === null); } $end = microtime(true); echo($end - $start) . "\n"; |
Das Ergebnis dabei ist:
"is_null($var)" vs. "$var === null" is_null($var): 0.162046194077 $var === null: 0.0550520420074
is_null ist also dreimal so langsam wie === null.
Ich habe den Test mal etwas verändert und habe mir die Frage gestellt, gibt es einen Unterschied zwischen === null und === NULL?
echo '"$var === nul"" vs. "$var === NULL"' . "\n"; $max = 100000; $varNull = null; $varNotNull = true; echo ' $var === null: '; $start = microtime(true); for ($i = 0; $i < $max; $i++) { ($varNull === null); ($varNotNull === null); } $end = microtime(true); echo($end - $start) . "\n"; echo ' $var === NULL: '; $start = microtime(true); for ($i = 0; $i < $max; $i++) { ($varNull === NULL); ($varNotNull === NULL); } $end = microtime(true); echo($end - $start) . "\n"; |
Interessanterweise gibt es dabei noch immer einen messbaren Unterschied:
"$var === null" vs. "$var === NULL" $var === null: 0.0449469089508 $var === NULL: 0.0551202297211
Ich habe den Test mehrmals durchlaufen lassen und das Erbenis war immer in etwa diesem Verhältnis.
Was ist eigentlich der Unterschied zwischen null und NULL? NULL ist eine Konstante mit dem Inhalt null. Die schnellste Variante ist also in der Tat === null. Besonders wenn man diese Prüfung in Schleifen durchführt kann sich das also schon etwas bemerkbar machen.
Und es gibt natürlich auch eine Möglichkeit bestehenden Code schnell mal damit zu optimieren:
find library/ -type f -name "*.php" -exec sed -i -r 's#([^\!])is_null\s*\(([^\(\)]*)\)#\1\2 === null#g' {} \; find library/ -type f -name "*.php" -exec sed -i -r 's#[\!]is_null\s*\(([^\(\)]*)\)#\1 !== null#g' {} \; |
Hey,
ich fand das total interessant und wollte das auch für true/TRUE testen, um deine Test aber nach zu voll ziehen habe ich auch die mal bei mir durch laufen lassen – und das Ergebnis ist verwirrend.
Beim Test „is_null($var)“ vs. „$var === null“ war auch bei mir is_null langsamer aber fast 3 Sek – wie kann das denn sein? ( Ich habe das Script mehrmals laufen lassen! 😉 )
Und beim zweiten Test konnte ich keinen „Sieger“ ausmachen bei mir war immer die Schleife schneller, die als zweites (letztes) lief – auch das kann ich mir nicht erklären!?
Das lässt sich mit true/TRUE bei mir auch feststellen.
Vll. hast du eine Idee?
mfg
IchBinIch
PS: Ich habe für meine Test nur „\n“ durch „“ ersetzt, der Rest ist Copy&Past…
Hmm eventuell spielt der Opcodecache da irgendwie rein? Ich probiere da mal aus die Reihenfolge zu tauschen…