mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Optimize SplFixedArray::fromArray() for packed arrays (#18196)
If the array is packed, then we don't have to loop to get the highest index. For this script: ```php $array = range(1, 100); for ($i=0;$i<1000000;$i++) { SplFixedArray::fromArray($array); } ``` On an i7-4790: ``` Benchmark 1: ./sapi/cli/php spl.php Time (mean ± σ): 376.5 ms ± 2.0 ms [User: 372.1 ms, System: 2.6 ms] Range (min … max): 373.7 ms … 379.5 ms 10 runs Benchmark 2: ./sapi/cli/php_old spl.php Time (mean ± σ): 511.6 ms ± 1.9 ms [User: 508.0 ms, System: 2.3 ms] Range (min … max): 509.2 ms … 515.1 ms 10 runs Summary ./sapi/cli/php spl.php ran 1.36 ± 0.01 times faster than ./sapi/cli/php_old spl.php ``` On an i7-1185G7: ``` Benchmark 1: ./sapi/cli/php spl.php Time (mean ± σ): 250.4 ms ± 3.5 ms [User: 246.6 ms, System: 2.6 ms] Range (min … max): 247.0 ms … 258.5 ms 11 runs Benchmark 2: ./sapi/cli/php_old spl.php Time (mean ± σ): 328.4 ms ± 1.0 ms [User: 324.4 ms, System: 3.8 ms] Range (min … max): 327.5 ms … 331.0 ms 10 runs Summary ./sapi/cli/php spl.php ran 1.31 ± 0.02 times faster than ./sapi/cli/php_old spl.php ``` Bonus: this also decreases the code size of the function.
This commit is contained in:
parent
f056636086
commit
e034b69fa6
1 changed files with 20 additions and 13 deletions
|
@ -733,22 +733,29 @@ PHP_METHOD(SplFixedArray, fromArray)
|
|||
zend_ulong num_index, max_index = 0;
|
||||
zend_long tmp;
|
||||
|
||||
ZEND_HASH_FOREACH_KEY(Z_ARRVAL_P(data), num_index, str_index) {
|
||||
if (str_index != NULL || (zend_long)num_index < 0) {
|
||||
zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "array must contain only positive integer keys");
|
||||
if (HT_IS_PACKED(Z_ARRVAL_P(data))) {
|
||||
/* If there are no holes, then nNumUsed is the number of elements.
|
||||
* If there are holes, then nNumUsed is the index of the last element. */
|
||||
tmp = Z_ARRVAL_P(data)->nNumUsed;
|
||||
} else {
|
||||
ZEND_HASH_MAP_FOREACH_KEY(Z_ARRVAL_P(data), num_index, str_index) {
|
||||
if (str_index != NULL || (zend_long)num_index < 0) {
|
||||
zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "array must contain only positive integer keys");
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
if (num_index > max_index) {
|
||||
max_index = num_index;
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
|
||||
tmp = max_index + 1;
|
||||
if (tmp <= 0) {
|
||||
zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "integer overflow detected");
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
if (num_index > max_index) {
|
||||
max_index = num_index;
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
|
||||
tmp = max_index + 1;
|
||||
if (tmp <= 0) {
|
||||
zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "integer overflow detected");
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
spl_fixedarray_init(&array, tmp);
|
||||
|
||||
ZEND_HASH_FOREACH_NUM_KEY_VAL(Z_ARRVAL_P(data), num_index, element) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue