Skip to content

Commit 74e3a69

Browse files
authored
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.
1 parent daf0765 commit 74e3a69

2 files changed

Lines changed: 8 additions & 5 deletions

File tree

‎UPGRADING‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1105,6 +1105,7 @@ PHP 8.6 UPGRADE NOTES
11051105
. Improved performance of array_walk().
11061106
. Improved performance of intval('+0b...', 2) and intval('0b...', 2).
11071107
. Improved performance of str_split().
1108+
. Improved performance of str_pad().
11081109

11091110
- URI:
11101111
. Improved performance of Uri\WhatWg\Url::parse() when collecting

‎ext/standard/string.c‎

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5891,13 +5891,15 @@ static void php_str_pad_fill(zend_string *result, size_t pad_chars, const char *
58915891
return;
58925892
}
58935893

5894+
const char *start = p;
58945895
const char *end = p + pad_chars;
5895-
while (p + pad_str_len <= end) {
5896-
p = zend_mempcpy(p, pad_str, pad_str_len);
5897-
}
5896+
size_t len = MIN(pad_str_len, pad_chars);
5897+
p = zend_mempcpy(p, pad_str, len);
58985898

5899-
if (p < end) {
5900-
memcpy(p, pad_str, end - p);
5899+
/* Double the filled area on each iteration. */
5900+
while (p < end) {
5901+
len = MIN(p - start, end - p);
5902+
p = zend_mempcpy(p, start, len);
59015903
}
59025904

59035905
ZSTR_LEN(result) += pad_chars;

0 commit comments

Comments
 (0)