Skip to content

Commit

Permalink
Speed up implod()'ing between 5% and 30% (by time)
Browse files Browse the repository at this point in the history
Significantly speed up implode()'ing on integers now...
Previously I accidentally committed the first part of the patch in 69b54ba
  • Loading branch information
bwoebi committed May 25, 2015
1 parent 31f3eeb commit bb55290
Showing 1 changed file with 30 additions and 8 deletions.
38 changes: 30 additions & 8 deletions ext/standard/string.c
Original file line number Diff line number Diff line change
Expand Up @@ -1218,28 +1218,50 @@ PHPAPI void php_implode(const zend_string *delim, zval *arr, zval *return_value)
} ZEND_HASH_FOREACH_END();
}

strings = emalloc(sizeof(zend_string *) * numelems);
strings = emalloc((sizeof(zend_long) + sizeof(zend_string *)) * numelems);
strptr = strings - 1;

ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(arr), tmp) {
*++strptr = zval_get_string(tmp);
len += (*strptr)->len;
if (Z_TYPE_P(tmp) == IS_LONG) {
*++strptr = NULL;
((zend_long *) (strings + numelems))[strptr - strings] = Z_LVAL_P(tmp);
len += (int) log10(Z_LVAL_P(tmp) < 0 ? -100 * ((double) Z_LVAL_P(tmp) - 0.001) : 10 * ((double) Z_LVAL_P(tmp) + 0.01));
} else {
*++strptr = zval_get_string(tmp);
len += (*strptr)->len;
}
} ZEND_HASH_FOREACH_END();

str = zend_string_alloc(len + (numelems - 1) * delim->len, 0);
cptr = str->val + str->len;
*cptr = 0;

do {
cptr -= (*strptr)->len;
memcpy(cptr, (*strptr)->val, (*strptr)->len);
zend_string_release(*strptr);
if (*strptr) {
cptr -= (*strptr)->len;
memcpy(cptr, (*strptr)->val, (*strptr)->len);
zend_string_release(*strptr);
} else {
char *oldPtr = cptr;
char oldVal = *cptr;
zend_long val = ((zend_long *) (strings + numelems))[strptr - strings];
cptr = zend_print_long_to_buf(cptr, val);
*oldPtr = oldVal;
}

cptr -= delim->len;
memcpy(cptr, delim->val, delim->len);
} while (--strptr > strings);
memcpy(str->val, (*strptr)->val, (*strptr)->len);
zend_string_release(*strptr);

if (*strptr) {
memcpy(str->val, (*strptr)->val, (*strptr)->len);
zend_string_release(*strptr);
} else {
char *oldPtr = cptr;
char oldVal = *cptr;
zend_print_long_to_buf(cptr, ((zend_long *) (strings + numelems))[strptr - strings]);
*oldPtr = oldVal;
}

efree(strings);
RETURN_NEW_STR(str);
Expand Down

0 comments on commit bb55290

Please sign in to comment.