mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Improve performance of array_walk() (#20322)
We never need to use refcounted copies for arguments because the copy to
the call frame already increments the refcount.
For the following benchmark:
```php
$a = range(0, 10);
for ($i = 0; $i < 1000000; $i++)
array_walk($a, fn ($val, $idx, $arg) => $val + $arg, 2);
```
On an i7-4790:
```
Benchmark 1: ./sapi/cli/php x.php
Time (mean ± σ): 593.0 ms ± 5.4 ms [User: 589.8 ms, System: 1.7 ms]
Range (min … max): 583.3 ms … 600.9 ms 10 runs
Benchmark 2: ./sapi/cli/php_old x.php
Time (mean ± σ): 637.8 ms ± 4.6 ms [User: 633.9 ms, System: 2.2 ms]
Range (min … max): 633.4 ms … 649.2 ms 10 runs
Summary
./sapi/cli/php x.php ran
1.08 ± 0.01 times faster than ./sapi/cli/php_old x.php
```
On an i7-1185G7:
```
Benchmark 1: ./sapi/cli/php x.php
Time (mean ± σ): 362.3 ms ± 2.0 ms [User: 359.9 ms, System: 1.9 ms]
Range (min … max): 359.6 ms … 367.1 ms 10 runs
Benchmark 2: ./sapi/cli/php_old x.php
Time (mean ± σ): 385.5 ms ± 1.8 ms [User: 383.2 ms, System: 1.9 ms]
Range (min … max): 381.5 ms … 387.2 ms 10 runs
Summary
./sapi/cli/php x.php ran
1.06 ± 0.01 times faster than ./sapi/cli/php_old x.php
```
This commit is contained in:
@@ -125,3 +125,4 @@ PHP 8.6 UPGRADE NOTES
|
||||
|
||||
- Standard:
|
||||
. Improved performance of array_fill_keys().
|
||||
. Improved performance of array_walk().
|
||||
|
||||
@@ -1457,7 +1457,7 @@ static zend_result php_array_walk(
|
||||
/* Set up known arguments */
|
||||
ZVAL_UNDEF(&args[1]);
|
||||
if (userdata) {
|
||||
ZVAL_COPY(&args[2], userdata);
|
||||
ZVAL_COPY_VALUE(&args[2], userdata);
|
||||
}
|
||||
|
||||
fci.retval = &retval;
|
||||
@@ -1531,21 +1531,14 @@ static zend_result php_array_walk(
|
||||
}
|
||||
zval_ptr_dtor(&ref);
|
||||
} else {
|
||||
ZVAL_COPY(&args[0], zv);
|
||||
ZVAL_COPY_VALUE(&args[0], zv);
|
||||
|
||||
/* Call the userland function */
|
||||
result = zend_call_function(&fci, &context->fci_cache);
|
||||
if (result == SUCCESS) {
|
||||
zval_ptr_dtor(&retval);
|
||||
}
|
||||
|
||||
zval_ptr_dtor(&args[0]);
|
||||
zval_ptr_dtor(&retval);
|
||||
}
|
||||
|
||||
if (Z_TYPE(args[1]) != IS_UNDEF) {
|
||||
zval_ptr_dtor(&args[1]);
|
||||
ZVAL_UNDEF(&args[1]);
|
||||
}
|
||||
zval_ptr_dtor_str(&args[1]);
|
||||
|
||||
if (result == FAILURE) {
|
||||
break;
|
||||
@@ -1565,9 +1558,6 @@ static zend_result php_array_walk(
|
||||
}
|
||||
} while (!EG(exception));
|
||||
|
||||
if (userdata) {
|
||||
zval_ptr_dtor(&args[2]);
|
||||
}
|
||||
zend_hash_iterator_del(ht_iter);
|
||||
return result;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user