Skip to content

Commit 7b6b233

Browse files
authored
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 ```
1 parent 84ff5d8 commit 7b6b233

File tree

3 files changed

+20
-3
lines changed

3 files changed

+20
-3
lines changed

UPGRADING

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,3 +122,6 @@ PHP 8.6 UPGRADE NOTES
122122

123123
- JSON:
124124
. Improve performance of encoding arrays and objects.
125+
126+
- Standard:
127+
. Improved performance of array_fill_keys().

Zend/zend_hash.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,17 @@ static zend_always_inline bool zend_hash_str_exists_ind(const HashTable *ht, con
473473
Z_TYPE_P(Z_INDIRECT_P(zv)) != IS_UNDEF);
474474
}
475475

476+
static zend_always_inline zval *zend_symtable_add(HashTable *ht, zend_string *key, zval *pData)
477+
{
478+
zend_ulong idx;
479+
480+
if (ZEND_HANDLE_NUMERIC(key, idx)) {
481+
return zend_hash_index_add(ht, idx, pData);
482+
} else {
483+
return zend_hash_add(ht, key, pData);
484+
}
485+
}
486+
476487
static zend_always_inline zval *zend_symtable_add_new(HashTable *ht, zend_string *key, zval *pData)
477488
{
478489
zend_ulong idx;

ext/standard/array.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2830,16 +2830,19 @@ PHP_FUNCTION(array_fill_keys)
28302830

28312831
ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(keys), entry) {
28322832
ZVAL_DEREF(entry);
2833-
Z_TRY_ADDREF_P(val);
28342833
if (Z_TYPE_P(entry) == IS_LONG) {
2835-
zend_hash_index_update(Z_ARRVAL_P(return_value), Z_LVAL_P(entry), val);
2834+
zend_hash_index_add(Z_ARRVAL_P(return_value), Z_LVAL_P(entry), val);
28362835
} else {
28372836
zend_string *tmp_key;
28382837
zend_string *key = zval_get_tmp_string(entry, &tmp_key);
2839-
zend_symtable_update(Z_ARRVAL_P(return_value), key, val);
2838+
zend_symtable_add(Z_ARRVAL_P(return_value), key, val);
28402839
zend_tmp_string_release(tmp_key);
28412840
}
28422841
} ZEND_HASH_FOREACH_END();
2842+
2843+
if (Z_REFCOUNTED_P(val)) {
2844+
GC_ADDREF_EX(Z_COUNTED_P(val), zend_hash_num_elements(Z_ARRVAL_P(return_value)));
2845+
}
28432846
}
28442847
/* }}} */
28452848

0 commit comments

Comments
 (0)