Skip to content

Commit 24d2823

Browse files
Optimize performances of str_pad()
1 parent ff810d5 commit 24d2823

File tree

1 file changed

+32
-5
lines changed

1 file changed

+32
-5
lines changed

ext/standard/string.c

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5737,6 +5737,29 @@ PHP_FUNCTION(substr_count)
57375737
}
57385738
/* }}} */
57395739

5740+
static zend_always_inline void php_str_pad_fill(zend_string *result, size_t pad_chars, const char *pad_str, size_t pad_str_len) {
5741+
char *dest = ZSTR_VAL(result) + ZSTR_LEN(result);
5742+
5743+
if (pad_str_len == 1) {
5744+
memset(dest, pad_str[0], pad_chars);
5745+
5746+
return;
5747+
}
5748+
5749+
size_t full_copies = pad_chars / pad_str_len;
5750+
size_t remainder = pad_chars % pad_str_len;
5751+
char *p = dest;
5752+
5753+
for (size_t j = 0; j < full_copies; ++j) {
5754+
memcpy(p, pad_str, pad_str_len);
5755+
p += pad_str_len;
5756+
}
5757+
5758+
if (remainder > 0) {
5759+
memcpy(p, pad_str, remainder);
5760+
}
5761+
}
5762+
57405763
/* {{{ Returns input string padded on the left or right to specified length with pad_string */
57415764
PHP_FUNCTION(str_pad)
57425765
{
@@ -5749,7 +5772,7 @@ PHP_FUNCTION(str_pad)
57495772
char *pad_str = " "; /* Pointer to padding string */
57505773
size_t pad_str_len = 1;
57515774
zend_long pad_type_val = PHP_STR_PAD_RIGHT; /* The padding type value */
5752-
size_t i, left_pad=0, right_pad=0;
5775+
size_t left_pad=0, right_pad=0;
57535776
zend_string *result = NULL; /* Resulting string */
57545777

57555778
ZEND_PARSE_PARAMETERS_START(2, 4)
@@ -5799,16 +5822,20 @@ PHP_FUNCTION(str_pad)
57995822
}
58005823

58015824
/* First we pad on the left. */
5802-
for (i = 0; i < left_pad; i++)
5803-
ZSTR_VAL(result)[ZSTR_LEN(result)++] = pad_str[i % pad_str_len];
5825+
if (left_pad > 0) {
5826+
php_str_pad_fill(result, left_pad, pad_str, pad_str_len);
5827+
ZSTR_LEN(result) += left_pad;
5828+
}
58045829

58055830
/* Then we copy the input string. */
58065831
memcpy(ZSTR_VAL(result) + ZSTR_LEN(result), ZSTR_VAL(input), ZSTR_LEN(input));
58075832
ZSTR_LEN(result) += ZSTR_LEN(input);
58085833

58095834
/* Finally, we pad on the right. */
5810-
for (i = 0; i < right_pad; i++)
5811-
ZSTR_VAL(result)[ZSTR_LEN(result)++] = pad_str[i % pad_str_len];
5835+
if (right_pad > 0) {
5836+
php_str_pad_fill(result, right_pad, pad_str, pad_str_len);
5837+
ZSTR_LEN(result) += right_pad;
5838+
}
58125839

58135840
ZSTR_VAL(result)[ZSTR_LEN(result)] = '\0';
58145841

0 commit comments

Comments
 (0)