PHP-Objektarrays werden nicht linear skaliert, während globale Arrays dies tun?
Es gibt ein schwerwiegendes Leistungsproblem bei der Verwendung von In-Object-Arrays als Eigenschaft im Vergleich zur Verwendung einer globalen PHP-Array-Variablen. Warum?
Um dieses Problem zu bewerten, habe ich den folgenden Benchmark erstellt, der ein immer größeres Array mit einer stdClass als Knoten speichert. Zwei Tests wurden unter Verwendung einer Array-Eigenschaft in einer Klasse und ein globales Array ausgeführt.
Der Testcode
ini_set('memory_limit', '2250M');
class MyTest {
public $storage = [];
public function push(){
$this->storage[] = [new stdClass()];
}
}
echo "Testing Objects".PHP_EOL;
for($size = 1000; $size < 5000000; $size *= 2) {
$start = milliseconds();
for ($a=new MyTest(), $i=0;$i<$size;$i++) {
$a->push();
}
$end = milliseconds();
echo "Array Size $size".PHP_EOL;
echo $end - $start . " milliseconds to perform".PHP_EOL;
}
echo "================".PHP_EOL;
echo "Testing Array".PHP_EOL;
for($size = 1000; $size < 5000000; $size *= 2) {
$start = milliseconds();
for ($a=[], $i=0;$i<$size;$i++) {
$a[] = [new stdClass()];
}
$end = milliseconds();
echo "Array Size $size".PHP_EOL;
echo $end - $start . " milliseconds to perform".PHP_EOL;
}
Und die schockierenden Ergebnisse:
Testing Objects
Array Size 1000
2 milliseconds to perform
Array Size 2000
3 milliseconds to perform
Array Size 4000
6 milliseconds to perform
Array Size 8000
12 milliseconds to perform
Array Size 16000
35 milliseconds to perform
Array Size 32000
97 milliseconds to perform
Array Size 64000
246 milliseconds to perform
Array Size 128000
677 milliseconds to perform
Array Size 256000
2271 milliseconds to perform
Array Size 512000
9244 milliseconds to perform
Array Size 1024000
31186 milliseconds to perform
Array Size 2048000
116123 milliseconds to perform
Array Size 4096000
495588 milliseconds to perform
================
Testing Array
Array Size 1000
1 milliseconds to perform
Array Size 2000
2 milliseconds to perform
Array Size 4000
4 milliseconds to perform
Array Size 8000
8 milliseconds to perform
Array Size 16000
28 milliseconds to perform
Array Size 32000
61 milliseconds to perform
Array Size 64000
114 milliseconds to perform
Array Size 128000
245 milliseconds to perform
Array Size 256000
494 milliseconds to perform
Array Size 512000
970 milliseconds to perform
Array Size 1024000
2003 milliseconds to perform
Array Size 2048000
4241 milliseconds to perform
Array Size 4096000
14260 milliseconds to perform
Abgesehen von dem offensichtlichen Overhead des Objekts, das sich selbst aufruft, wird die Eigenschaft des Objekt-Arrays jetzt schrecklich oft 3-4 mal länger skaliert, wenn das Array größer wird. Dies ist jedoch bei der globalen Standard-Array-Variablen nicht der Fall.
Irgendwelche Gedanken oder Antworten zu diesem Problem und ist dies ein möglicher Fehler mit der PHP-Engine?