From: Ilia Alshanetsky Date: Sat, 10 Jun 2006 15:51:23 +0000 (+0000) Subject: MFB: Improved performance of str_replace() when doing 1 char to 1 char or 1 X-Git-Tag: RELEASE_1_0_0RC1~2751 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6434512a05b5799d37b3fd565989b83f4db45348;p=php MFB: Improved performance of str_replace() when doing 1 char to 1 char or 1 char to many chars replacement by 30-40%. --- diff --git a/ext/standard/string.c b/ext/standard/string.c index 978546e9e7..bc580eb314 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -4551,10 +4551,18 @@ PHPAPI int php_char_to_str_ex(char *str, uint len, char from, char *to, int to_l int char_count = 0; int replaced = 0; char *source, *target, *tmp, *source_end=str+len, *tmp_end = NULL; - - for (source = str; source < source_end; source++) { - if ((case_sensitivity && *source == from) || (!case_sensitivity && tolower(*source) == tolower(from))) { + + if (case_sensitivity) { + char *p = str, *e = p + len; + while ((p = memchr(p, from, (e - p)))) { char_count++; + p++; + } + } else { + for (source = str; source < source_end; source++) { + if (tolower(*source) == tolower(from)) { + char_count++; + } } } @@ -4566,20 +4574,36 @@ PHPAPI int php_char_to_str_ex(char *str, uint len, char from, char *to, int to_l Z_STRLEN_P(result) = len + (char_count * (to_len - 1)); Z_STRVAL_P(result) = target = emalloc(Z_STRLEN_P(result) + 1); Z_TYPE_P(result) = IS_STRING; - - for (source = str; source < source_end; source++) { - if ((case_sensitivity && *source == from) || (!case_sensitivity && tolower(*source) == tolower(from))) { - replaced = 1; - if (replace_count) { - *replace_count += 1; - } - for (tmp = to, tmp_end = tmp+to_len; tmp < tmp_end; tmp++) { - *target = *tmp; + + if (case_sensitivity) { + char *p = str, *e = p + len, *s = str; + while ((p = memchr(p, from, (e - p)))) { + memcpy(target, s, (p - s)); + target += p - s; + memcpy(target, to, to_len); + target += to_len; + p++; + s = p; + } + if (s < e) { + memcpy(target, s, (e - s)); + target += e - s; + } + } else { + for (source = str; source < source_end; source++) { + if (tolower(*source) == tolower(from)) { + replaced = 1; + if (replace_count) { + *replace_count += 1; + } + for (tmp = to, tmp_end = tmp+to_len; tmp < tmp_end; tmp++) { + *target = *tmp; + target++; + } + } else { + *target = *source; target++; } - } else { - *target = *source; - target++; } } *target = 0;