From 37d88ca5a029603fa8eedd0116b6d9e524e1839b Mon Sep 17 00:00:00 2001 From: Ilia Alshanetsky Date: Sat, 10 Jun 2006 15:29:06 +0000 Subject: [PATCH] Improved performance of str_replace() when doing 1 char to 1 char or 1 char to many chars replacement by 30-40%. --- NEWS | 2 ++ ext/standard/string.c | 54 +++++++++++++++++++++++++++++++------------ 2 files changed, 41 insertions(+), 15 deletions(-) diff --git a/NEWS b/NEWS index fb009debd8..4135c94e4f 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,8 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? 2006, PHP 5.2.0 +- Improved performance of str_replace() when doing 1 char to 1 char or 1 char + to many chars replacement by 30-40%. (Ilia) - Added memory_get_peak_usage() function for retrieving peak memory usage of a PHP script. (Ilia) - Changed Apache 2 Handler SAPI to call ap_set_content_type() once only. (Mike) diff --git a/ext/standard/string.c b/ext/standard/string.c index da735dad00..a3707bad21 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -3022,10 +3022,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++; + } } } @@ -3037,20 +3045,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; -- 2.40.0