Skip to content

Commit bb55290

Browse files
committed
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 69b54ba
1 parent 31f3eeb commit bb55290

File tree

1 file changed

+30
-8
lines changed

1 file changed

+30
-8
lines changed

ext/standard/string.c

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1218,28 +1218,50 @@ PHPAPI void php_implode(const zend_string *delim, zval *arr, zval *return_value)
12181218
} ZEND_HASH_FOREACH_END();
12191219
}
12201220

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

12241224
ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(arr), tmp) {
1225-
*++strptr = zval_get_string(tmp);
1226-
len += (*strptr)->len;
1225+
if (Z_TYPE_P(tmp) == IS_LONG) {
1226+
*++strptr = NULL;
1227+
((zend_long *) (strings + numelems))[strptr - strings] = Z_LVAL_P(tmp);
1228+
len += (int) log10(Z_LVAL_P(tmp) < 0 ? -100 * ((double) Z_LVAL_P(tmp) - 0.001) : 10 * ((double) Z_LVAL_P(tmp) + 0.01));
1229+
} else {
1230+
*++strptr = zval_get_string(tmp);
1231+
len += (*strptr)->len;
1232+
}
12271233
} ZEND_HASH_FOREACH_END();
12281234

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

12331239
do {
1234-
cptr -= (*strptr)->len;
1235-
memcpy(cptr, (*strptr)->val, (*strptr)->len);
1236-
zend_string_release(*strptr);
1240+
if (*strptr) {
1241+
cptr -= (*strptr)->len;
1242+
memcpy(cptr, (*strptr)->val, (*strptr)->len);
1243+
zend_string_release(*strptr);
1244+
} else {
1245+
char *oldPtr = cptr;
1246+
char oldVal = *cptr;
1247+
zend_long val = ((zend_long *) (strings + numelems))[strptr - strings];
1248+
cptr = zend_print_long_to_buf(cptr, val);
1249+
*oldPtr = oldVal;
1250+
}
12371251

12381252
cptr -= delim->len;
12391253
memcpy(cptr, delim->val, delim->len);
12401254
} while (--strptr > strings);
1241-
memcpy(str->val, (*strptr)->val, (*strptr)->len);
1242-
zend_string_release(*strptr);
1255+
1256+
if (*strptr) {
1257+
memcpy(str->val, (*strptr)->val, (*strptr)->len);
1258+
zend_string_release(*strptr);
1259+
} else {
1260+
char *oldPtr = cptr;
1261+
char oldVal = *cptr;
1262+
zend_print_long_to_buf(cptr, ((zend_long *) (strings + numelems))[strptr - strings]);
1263+
*oldPtr = oldVal;
1264+
}
12431265

12441266
efree(strings);
12451267
RETURN_NEW_STR(str);

0 commit comments

Comments
 (0)