[php-src] Issue #9429: array_key_exists on $GLOBALS takes linear time in PHP 8.1.0+

From: Date: Fri, 26 Aug 2022 09:18:25 +0000
Subject: [php-src] Issue #9429: array_key_exists on $GLOBALS takes linear time in PHP 8.1.0+
Groups: php.bugs 
Request: Send a blank email to php-bugs+get-242313@lists.php.net to get a copy of this message
Issue: https://github.com/php/php-src/issues/9429 Author: leejt ### Description Compare the following in PHP 8.0.22 vs 8.1.9 (https://3v4l.org/4kBiT) ```php <?php $a = []; for ($i = 0; $i < 100000; $i++) { $GLOBALS["a$i"] = rand(0, 1000000); $a["a$i"] = rand(0, 1000000); } $start = microtime(true); for ($runs = 1000; $runs > 0; $runs--) { array_key_exists('a1111111', $GLOBALS); } $end = microtime(true); printf("[GLOBALS]array_key_exists() took %.5f seconds\n", $end - $start); ``` It takes 0.00002 seconds in 8.0.22, and 1.9 seconds in 8.1.9. Further testing makes it clear that the speed of array_key_exists on $GLOBALS increases linearly with the size of $GLOBALS. This regression doesn't affect array_key_exists on non-$GLOBALS arrays, and doesn't affect the speed of isset($GLOBALS[$foo]. The commit that introduced the slowdown was https://github.com/php/php-src/commit/3c68f38fdaec7a6f81f986a639bdd29716cf8f22, which restricted usage of $GLOBALS in various ways. I'm not sure if this particular side effect was known or intended. array_key_exists is used somewhat often on $GLOBALS in MediaWiki, most prominently [here](https://github.com/wikimedia/mediawiki/blob/master/includes/config/GlobalVarConfig.php#L91). The behavior can be mostly replaced by calling isset($GLOBALS[$foo], which remains fast, although that has different semantics when the value is null. I'm not aware of a better way to get the full behavior of array_key_exists($foo, $GLOBALS) in constant-time in 8.1+. ### PHP Version PHP 8.1.9 ### Operating System Ubuntu 20.04

« previous php.bugs (#242313) next »