From feee37a17aa09d32ef9841079697f441fda3493a Mon Sep 17 00:00:00 2001 From: Sara Golemon Date: Wed, 3 Dec 2003 01:31:56 +0000 Subject: [PATCH] Optimize strrpos/strripos for single char strings and fix offset to report correctly --- ext/standard/string.c | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/ext/standard/string.c b/ext/standard/string.c index 5f55dd9da0..859e9b1484 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -1606,9 +1606,20 @@ PHP_FUNCTION(strrpos) } } + if (needle_len == 1) { + /* Single character search can shortcut memcmps */ + while (e >= p) { + if (*e == *needle) { + RETURN_LONG(e - p + (offset > 0 ? offset : 0)); + } + e--; + } + RETURN_FALSE; + } + while (e >= p) { if (memcmp(e, needle, needle_len) == 0) { - RETURN_LONG(e - p); + RETURN_LONG(e - p + (offset > 0 ? offset : 0)); } e--; } @@ -1646,6 +1657,27 @@ PHP_FUNCTION(strripos) RETURN_FALSE; } + if (needle_len == 1) { + /* Single character search can shortcut memcmps + Can also avoid tolower emallocs */ + if (offset >= 0) { + p = haystack + offset; + e = haystack + haystack_len - 1; + } else { + p = haystack; + e = haystack + haystack_len - offset; + } + /* Borrow that ord_needle buffer to avoid repeatedly tolower()ing needle */ + *ord_needle = tolower(*needle); + while (e >= p) { + if (tolower(*e) == *ord_needle) { + RETURN_LONG(e - p + (offset > 0 ? offset : 0)); + } + e--; + } + RETURN_FALSE; + } + needle_dup = estrndup(needle, needle_len); php_strtolower(needle_dup, needle_len); haystack_dup = estrndup(haystack, haystack_len); @@ -1667,7 +1699,7 @@ PHP_FUNCTION(strripos) if (memcmp(e, needle_dup, needle_len) == 0) { efree(haystack_dup); efree(needle_dup); - RETURN_LONG(e - p); + RETURN_LONG(e - p + (offset > 0 ? offset : 0)); } e--; } -- 2.50.1