From: Bob Weinand Date: Mon, 25 May 2015 23:12:23 +0000 (+0200) Subject: Speed up implod()'ing between 5% and 30% (by time) X-Git-Tag: PRE_PHP7_NSAPI_REMOVAL~32^2~2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bb552908a05ba26c2a12cc111a4cdab6a53a4c31;p=php Speed up implod()'ing between 5% and 30% (by time) Significantly speed up implode()'ing on integers now... Previously I accidentally committed the first part of the patch in 69b54ba926b714dff0f8b54bea385e9a278c5849 --- diff --git a/ext/standard/string.c b/ext/standard/string.c index d3d8848128..7dad1b67ff 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -1218,12 +1218,18 @@ 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); @@ -1231,15 +1237,31 @@ PHPAPI void php_implode(const zend_string *delim, zval *arr, zval *return_value) *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);