summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIlia Alshanetsky <iliaa@php.net>2006-06-10 15:29:06 +0000
committerIlia Alshanetsky <iliaa@php.net>2006-06-10 15:29:06 +0000
commit37d88ca5a029603fa8eedd0116b6d9e524e1839b (patch)
tree97a1944db4e2bb2b6e98b0bb253447981cc5d428
parent13fe33c2dfd669fa01793841c7a3e289be1e28a7 (diff)
downloadphp-git-37d88ca5a029603fa8eedd0116b6d9e524e1839b.tar.gz
Improved performance of str_replace() when doing 1 char to 1 char or 1 char
to many chars replacement by 30-40%.
-rw-r--r--NEWS2
-rw-r--r--ext/standard/string.c54
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;