Commit 74e3a69df1a for php.net
commit 74e3a69df1a5e86b1874ec562831ed4db58f7a38
Author: Weilin Du <weilindu@php.net>
Date: Sat Sep 12 13:28:03 2026 +0800
ext/standard: Optimize str_pad() using doubling copies (#23661)
This PR optimizes the user-visible `str_pad()` by reducing repeated small
copy operations during padding. In `php_str_pad_fill()`, the algorithm now uses
doubling copies to grow the written region exponentially. This lowers memcpy counts
and improves throughput for large repeated-pattern padding workloads.
Added `str_pad_repeated_pattern.phpt` to validate repeated pattern and partial-tail
boundaries, including multi-byte patterns and all pad directions. Behavior is
unchanged; this is a performance-only change and is now recorded in the PHP 8.6
performance changelog.
diff --git a/UPGRADING b/UPGRADING
index a866bc223e4..3980faa4294 100644
--- a/UPGRADING
+++ b/UPGRADING
@@ -1105,6 +1105,7 @@ PHP 8.6 UPGRADE NOTES
. Improved performance of array_walk().
. Improved performance of intval('+0b...', 2) and intval('0b...', 2).
. Improved performance of str_split().
+ . Improved performance of str_pad().
- URI:
. Improved performance of Uri\WhatWg\Url::parse() when collecting
diff --git a/ext/standard/string.c b/ext/standard/string.c
index 04c3c21b286..577d4267ed2 100644
--- a/ext/standard/string.c
+++ b/ext/standard/string.c
@@ -5891,13 +5891,15 @@ static void php_str_pad_fill(zend_string *result, size_t pad_chars, const char *
return;
}
+ const char *start = p;
const char *end = p + pad_chars;
- while (p + pad_str_len <= end) {
- p = zend_mempcpy(p, pad_str, pad_str_len);
- }
+ size_t len = MIN(pad_str_len, pad_chars);
+ p = zend_mempcpy(p, pad_str, len);
- if (p < end) {
- memcpy(p, pad_str, end - p);
+ /* Double the filled area on each iteration. */
+ while (p < end) {
+ len = MIN(p - start, end - p);
+ p = zend_mempcpy(p, start, len);
}
ZSTR_LEN(result) += pad_chars;