Optimize SplFixedArray::toArray() (#18190)

We can use the optimized packed filling code instead of going through
all the logic of the zend_hash update APIs.

For this script:
```php
$test = new SplFixedArray(4);
$test[0] = 0;
$test[1] = 1;
$test[2] = 2;
$test[3] = 3;

for ($i = 0 ; $i< 5000000; $i++)
	$test->toArray();
```

On an i7-4790:
```
Benchmark 1: ./sapi/cli/php toarray.php
  Time (mean ± σ):     170.0 ms ±   1.8 ms    [User: 167.3 ms, System: 2.2 ms]
  Range (min … max):   166.9 ms … 173.0 ms    17 runs

Benchmark 2: ./sapi/cli/php_old toarray.php
  Time (mean ± σ):     215.7 ms ±   3.6 ms    [User: 211.9 ms, System: 3.0 ms]
  Range (min … max):   211.3 ms … 222.0 ms    13 runs

Summary
  ./sapi/cli/php toarray.php ran
    1.27 ± 0.02 times faster than ./sapi/cli/php_old toarray.php
```

On an i7-1185G7:
```

Benchmark 1: ./sapi/cli/php toarray.php
  Time (mean ± σ):     112.6 ms ±   1.4 ms    [User: 109.6 ms, System: 2.9 ms]
  Range (min … max):   111.1 ms … 116.4 ms    25 runs

Benchmark 2: ./sapi/cli/php_old toarray.php
  Time (mean ± σ):     145.3 ms ±   2.8 ms    [User: 141.8 ms, System: 3.4 ms]
  Range (min … max):   142.6 ms … 151.8 ms    20 runs

Summary
  ./sapi/cli/php toarray.php  ran
    1.29 ± 0.03 times faster than ./sapi/cli/php_old toarray.php
```
This commit is contained in:
Niels Dossche 2025-03-30 18:09:01 +02:00 committed by GitHub
parent 07470c3dd0
commit d13d9b3c24
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -695,11 +695,16 @@ PHP_METHOD(SplFixedArray, toArray)
intern = Z_SPLFIXEDARRAY_P(ZEND_THIS); intern = Z_SPLFIXEDARRAY_P(ZEND_THIS);
if (!spl_fixedarray_empty(&intern->array)) { if (!spl_fixedarray_empty(&intern->array)) {
array_init(return_value); array_init_size(return_value, intern->array.size);
for (zend_long i = 0; i < intern->array.size; i++) { HashTable *ht = Z_ARRVAL_P(return_value);
zend_hash_index_update(Z_ARRVAL_P(return_value), i, &intern->array.elements[i]); zend_hash_real_init_packed(ht);
Z_TRY_ADDREF(intern->array.elements[i]);
} ZEND_HASH_FILL_PACKED(ht) {
for (zend_long i = 0; i < intern->array.size; i++) {
ZEND_HASH_FILL_ADD(&intern->array.elements[i]);
Z_TRY_ADDREF(intern->array.elements[i]);
}
} ZEND_HASH_FILL_END();
} else { } else {
RETURN_EMPTY_ARRAY(); RETURN_EMPTY_ARRAY();
} }