Skip to content

Commit 80e4278

Browse files
Optimize performances of str_pad() (#19272)
1 parent dfdf992 commit 80e4278

File tree

1 file changed

+28
-5
lines changed

1 file changed

+28
-5
lines changed

ext/standard/string.c

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5756,6 +5756,27 @@ PHP_FUNCTION(substr_count)
57565756
}
57575757
/* }}} */
57585758

5759+
static void php_str_pad_fill(zend_string *result, size_t pad_chars, const char *pad_str, size_t pad_str_len) {
5760+
char *p = ZSTR_VAL(result) + ZSTR_LEN(result);
5761+
5762+
if (pad_str_len == 1) {
5763+
memset(p, pad_str[0], pad_chars);
5764+
ZSTR_LEN(result) += pad_chars;
5765+
return;
5766+
}
5767+
5768+
const char *end = p + pad_chars;
5769+
while (p + pad_str_len <= end) {
5770+
p = zend_mempcpy(p, pad_str, pad_str_len);
5771+
}
5772+
5773+
if (p < end) {
5774+
memcpy(p, pad_str, end - p);
5775+
}
5776+
5777+
ZSTR_LEN(result) += pad_chars;
5778+
}
5779+
57595780
/* {{{ Returns input string padded on the left or right to specified length with pad_string */
57605781
PHP_FUNCTION(str_pad)
57615782
{
@@ -5768,7 +5789,7 @@ PHP_FUNCTION(str_pad)
57685789
char *pad_str = " "; /* Pointer to padding string */
57695790
size_t pad_str_len = 1;
57705791
zend_long pad_type_val = PHP_STR_PAD_RIGHT; /* The padding type value */
5771-
size_t i, left_pad=0, right_pad=0;
5792+
size_t left_pad=0, right_pad=0;
57725793
zend_string *result = NULL; /* Resulting string */
57735794

57745795
ZEND_PARSE_PARAMETERS_START(2, 4)
@@ -5818,16 +5839,18 @@ PHP_FUNCTION(str_pad)
58185839
}
58195840

58205841
/* First we pad on the left. */
5821-
for (i = 0; i < left_pad; i++)
5822-
ZSTR_VAL(result)[ZSTR_LEN(result)++] = pad_str[i % pad_str_len];
5842+
if (left_pad > 0) {
5843+
php_str_pad_fill(result, left_pad, pad_str, pad_str_len);
5844+
}
58235845

58245846
/* Then we copy the input string. */
58255847
memcpy(ZSTR_VAL(result) + ZSTR_LEN(result), ZSTR_VAL(input), ZSTR_LEN(input));
58265848
ZSTR_LEN(result) += ZSTR_LEN(input);
58275849

58285850
/* Finally, we pad on the right. */
5829-
for (i = 0; i < right_pad; i++)
5830-
ZSTR_VAL(result)[ZSTR_LEN(result)++] = pad_str[i % pad_str_len];
5851+
if (right_pad > 0) {
5852+
php_str_pad_fill(result, right_pad, pad_str, pad_str_len);
5853+
}
58315854

58325855
ZSTR_VAL(result)[ZSTR_LEN(result)] = '\0';
58335856

0 commit comments

Comments
 (0)