Skip to content

Commit 2ea2b66

Browse files
author
Ilia Alshanetsky
committed
Optimized str_repeat() function, it is now 10x faster on 1 byte multipliers
and 5-6x faster on multi-byte multipliers.
1 parent 39b0eb9 commit 2ea2b66

File tree

1 file changed

+20
-9
lines changed

1 file changed

+20
-9
lines changed

ext/standard/string.c

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3537,10 +3537,9 @@ PHPAPI void php_strip_tags(char *rbuf, int len, int *stateptr, char *allow, int
35373537
PHP_FUNCTION(str_repeat)
35383538
{
35393539
zval **input_str; /* Input string */
3540-
zval **mult; /* Multiplier */
3541-
char *result; /* Resulting string */
3542-
int result_len; /* Length of the resulting string */
3543-
int i;
3540+
zval **mult; /* Multiplier */
3541+
char *result; /* Resulting string */
3542+
int result_len; /* Length of the resulting string */
35443543

35453544
if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &input_str, &mult) == FAILURE) {
35463545
WRONG_PARAM_COUNT;
@@ -3567,12 +3566,24 @@ PHP_FUNCTION(str_repeat)
35673566
result_len = Z_STRLEN_PP(input_str) * Z_LVAL_PP(mult);
35683567
result = (char *)emalloc(result_len + 1);
35693568

3570-
/* Copy the input string into the result as many times as necessary */
3571-
for (i = 0; i < Z_LVAL_PP(mult); i++) {
3572-
memcpy(result + Z_STRLEN_PP(input_str) * i,
3573-
Z_STRVAL_PP(input_str),
3574-
Z_STRLEN_PP(input_str));
3569+
/* Heavy optimization for situations where multiplier is 1 byte long */
3570+
if (Z_LVAL_PP(mult) == 1) {
3571+
memset(result, *(Z_STRVAL_PP(input_str)), Z_LVAL_PP(mult));
3572+
} else {
3573+
char *s, *e, *ee;
3574+
int l=0;
3575+
memcpy(result, Z_STRVAL_PP(input_str), Z_STRLEN_PP(input_str));
3576+
s = result;
3577+
e = result + Z_STRLEN_PP(input_str);
3578+
ee = result + result_len;
3579+
3580+
while (e<ee) {
3581+
l = (e-s) < (ee-e) ? (e-s) : (ee-e);
3582+
memmove(e, s, l);
3583+
e += l;
3584+
}
35753585
}
3586+
35763587
result[result_len] = '\0';
35773588

35783589
RETURN_STRINGL(result, result_len, 0);

0 commit comments

Comments
 (0)