„$var === null“ vs. „is_null($var)“

Posted by in PHP

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' {} \;