Commit a8caefcafbb for php
commit a8caefcafbb2e761c5edbe0ddf12e600d3de2062
Author: mehmetcan <2010841+mehmetcansahin@users.noreply.github.com>
Date: Thu Sep 24 21:22:09 2026 +0300
array_splice(): Presize the result when nothing is removed (#23886)
The output hash was sized for the replacement only, so copying the kept
input elements grew it by doubling. Size it for the final element count.
diff --git a/NEWS b/NEWS
index 01eb73754ac..2aaa3c4c387 100644
--- a/NEWS
+++ b/NEWS
@@ -6,4 +6,8 @@ PHP NEWS
. Fixed Collator attribute and strength methods not rejecting an
unconstructed Collator. (Ilia Alshanetsky)
+- Standard:
+ . Improved performance of array_splice() when inserting without removing
+ elements. (mehmetcansahin)
+
<<< NOTE: Insert NEWS from last stable release here prior to actual release! >>>
diff --git a/UPGRADING b/UPGRADING
index f66d5b6987f..8c9bc4dac3f 100644
--- a/UPGRADING
+++ b/UPGRADING
@@ -70,3 +70,7 @@ PHP 8.7 UPGRADE NOTES
========================================
14. Performance Improvements
========================================
+
+- Standard:
+ . Improved performance of array_splice() when inserting without removing
+ elements.
diff --git a/ext/standard/array.c b/ext/standard/array.c
index 4c3704c8510..a434589771b 100644
--- a/ext/standard/array.c
+++ b/ext/standard/array.c
@@ -3280,8 +3280,13 @@ static void php_splice(HashTable *in_hash, zend_long offset, zend_long length, H
length = num_in - offset;
}
+ /* Number of entries in the output hash: the input entries that are kept
+ * plus the replacement entries. After clamping, a non-positive length
+ * removes nothing, so all input entries are kept. */
+ uint32_t num_out = num_in - MAX(length, 0) + (replace ? zend_hash_num_elements(replace) : 0);
+
/* Create and initialize output hash */
- zend_hash_init(&out_hash, (length > 0 ? num_in - length : 0) + (replace ? zend_hash_num_elements(replace) : 0), NULL, ZVAL_PTR_DTOR, 0);
+ zend_hash_init(&out_hash, num_out, NULL, ZVAL_PTR_DTOR, 0);
if (HT_IS_PACKED(in_hash)) {
/* Start at the beginning of the input hash and copy entries to output hash until offset is reached */