mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Optimize array_fill_keys() (#20347)
Move the refcount update outside of the loop.
For the following benchmark:
```php
$r = range(0, 1000);
$v = new stdClass();
for ($i = 0; $i < 100000; $i++) {
array_fill_keys($r, $v);
}
```
On an i7-4790:
```
Benchmark 1: ./sapi/cli/php_old ../x.php
Time (mean ± σ): 507.5 ms ± 4.8 ms [User: 505.1 ms, System: 1.2 ms]
Range (min … max): 501.2 ms … 518.4 ms 10 runs
Benchmark 2: ./sapi/cli/php ../x.php
Time (mean ± σ): 479.8 ms ± 3.1 ms [User: 476.8 ms, System: 1.8 ms]
Range (min … max): 475.0 ms … 486.7 ms 10 runs
Summary
./sapi/cli/php ../x.php ran
1.06 ± 0.01 times faster than ./sapi/cli/php_old ../x.php
```
On an i7-1185G7:
```
Benchmark 1: ./sapi/cli/php x.php
Time (mean ± σ): 343.9 ms ± 3.1 ms [User: 341.1 ms, System: 2.3 ms]
Range (min … max): 337.9 ms … 347.8 ms 10 runs
Benchmark 2: ./sapi/cli/php_old x.php
Time (mean ± σ): 357.8 ms ± 2.3 ms [User: 355.7 ms, System: 1.6 ms]
Range (min … max): 355.0 ms … 362.6 ms 10 runs
Summary
./sapi/cli/php x.php ran
1.04 ± 0.01 times faster than ./sapi/cli/php_old x.php
```
This commit is contained in:
@@ -122,3 +122,6 @@ PHP 8.6 UPGRADE NOTES
|
||||
|
||||
- JSON:
|
||||
. Improve performance of encoding arrays and objects.
|
||||
|
||||
- Standard:
|
||||
. Improved performance of array_fill_keys().
|
||||
|
||||
@@ -473,6 +473,17 @@ static zend_always_inline bool zend_hash_str_exists_ind(const HashTable *ht, con
|
||||
Z_TYPE_P(Z_INDIRECT_P(zv)) != IS_UNDEF);
|
||||
}
|
||||
|
||||
static zend_always_inline zval *zend_symtable_add(HashTable *ht, zend_string *key, zval *pData)
|
||||
{
|
||||
zend_ulong idx;
|
||||
|
||||
if (ZEND_HANDLE_NUMERIC(key, idx)) {
|
||||
return zend_hash_index_add(ht, idx, pData);
|
||||
} else {
|
||||
return zend_hash_add(ht, key, pData);
|
||||
}
|
||||
}
|
||||
|
||||
static zend_always_inline zval *zend_symtable_add_new(HashTable *ht, zend_string *key, zval *pData)
|
||||
{
|
||||
zend_ulong idx;
|
||||
|
||||
@@ -2830,16 +2830,19 @@ PHP_FUNCTION(array_fill_keys)
|
||||
|
||||
ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(keys), entry) {
|
||||
ZVAL_DEREF(entry);
|
||||
Z_TRY_ADDREF_P(val);
|
||||
if (Z_TYPE_P(entry) == IS_LONG) {
|
||||
zend_hash_index_update(Z_ARRVAL_P(return_value), Z_LVAL_P(entry), val);
|
||||
zend_hash_index_add(Z_ARRVAL_P(return_value), Z_LVAL_P(entry), val);
|
||||
} else {
|
||||
zend_string *tmp_key;
|
||||
zend_string *key = zval_get_tmp_string(entry, &tmp_key);
|
||||
zend_symtable_update(Z_ARRVAL_P(return_value), key, val);
|
||||
zend_symtable_add(Z_ARRVAL_P(return_value), key, val);
|
||||
zend_tmp_string_release(tmp_key);
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
|
||||
if (Z_REFCOUNTED_P(val)) {
|
||||
GC_ADDREF_EX(Z_COUNTED_P(val), zend_hash_num_elements(Z_ARRVAL_P(return_value)));
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user