Avoid rebuilding the property table when possible in SplFixedArray's gc handler (#18195)

If there is not yet a dynamic property, and there are no class properties,
then we know that we don't have to build a properties table.

For this (micro-bench) script:
```php
function x() {
    $fa = new SplFixedArray(1);
    $fa[0] = $fa;
}
for ($i=0;$i<1000000;$i++)
    x();
```

On an i7-4790:
```
Benchmark 1: ./sapi/cli/php spl.php
  Time (mean ± σ):     140.9 ms ±   1.2 ms    [User: 137.5 ms, System: 2.7 ms]
  Range (min … max):   138.9 ms … 144.9 ms    21 runs

Benchmark 2: ./sapi/cli/php_old spl.php
  Time (mean ± σ):     162.0 ms ±   3.8 ms    [User: 157.7 ms, System: 3.2 ms]
  Range (min … max):   158.5 ms … 175.0 ms    17 runs

Summary
  ./sapi/cli/php spl.php  ran
    1.15 ± 0.03 times faster than ./sapi/cli/php_old spl.php
```
This commit is contained in:
Niels Dossche 2025-03-30 18:36:38 +02:00 committed by GitHub
parent 24fbe2d61e
commit f056636086
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -212,12 +212,15 @@ static void spl_fixedarray_resize(spl_fixedarray *array, zend_long size)
static HashTable* spl_fixedarray_object_get_gc(zend_object *obj, zval **table, int *n) static HashTable* spl_fixedarray_object_get_gc(zend_object *obj, zval **table, int *n)
{ {
spl_fixedarray_object *intern = spl_fixed_array_from_obj(obj); spl_fixedarray_object *intern = spl_fixed_array_from_obj(obj);
HashTable *ht = zend_std_get_properties(obj);
*table = intern->array.elements; *table = intern->array.elements;
*n = (int)intern->array.size; *n = (int)intern->array.size;
return ht; if (obj->properties == NULL && obj->ce->default_properties_count == 0) {
return NULL;
} else {
return zend_std_get_properties(obj);
}
} }
static HashTable* spl_fixedarray_object_get_properties_for(zend_object *obj, zend_prop_purpose purpose) static HashTable* spl_fixedarray_object_get_properties_for(zend_object *obj, zend_prop_purpose purpose)