Le jeudi 6 octobre 2011 02:06:30, Victor Stinner a écrit :
> The rfind case is really strange: the code between Python 3.2 and 3.3 is
> exactly the same. Even in Python 3.2: rfind looks twice faster than find:
>
> ("AB"*300+"C").find("BC") (*1000) : 1.21
> ("C"+"AB"*300).rfind("CA") (*1000) : 0.57
It looks to be a gcc bug: using attached patch (written by Antoine), str.find()
is a little bit faster. With the patch, the function does the same memory
access, but it generates a different machine code.
I don't know exactly the difference yet, but it may be related to the CMOVNE
instruction (which looks to be slower than a classical conditional jump, JNE).
Victor
diff --git a/Objects/stringlib/fastsearch.h b/Objects/stringlib/fastsearch.h
--- a/Objects/stringlib/fastsearch.h
+++ b/Objects/stringlib/fastsearch.h
@@ -76,6 +76,8 @@ FASTSEARCH(const STRINGLIB_CHAR* s, Py_s
mask = 0;
if (mode != FAST_RSEARCH) {
+ const STRINGLIB_CHAR *ss = s + m - 1;
+ const STRINGLIB_CHAR *pp = p + m - 1;
/* create compressed boyer-moore delta 1 table */
@@ -90,7 +92,7 @@ FASTSEARCH(const STRINGLIB_CHAR* s, Py_s
for (i = 0; i <= w; i++) {
/* note: using mlast in the skip path slows things down on x86 */
- if (s[i+m-1] == p[m-1]) {
+ if (ss[i] == pp[0]) {
/* candidate match */
for (j = 0; j < mlast; j++)
if (s[i+j] != p[j])
@@ -106,13 +108,13 @@ FASTSEARCH(const STRINGLIB_CHAR* s, Py_s
continue;
}
/* miss: check if next character is part of pattern */
- if (!STRINGLIB_BLOOM(mask, s[i+m]))
+ if (!STRINGLIB_BLOOM(mask, ss[i+1]))
i = i + m;
else
i = i + skip;
} else {
/* skip: check if next character is part of pattern */
- if (!STRINGLIB_BLOOM(mask, s[i+m]))
+ if (!STRINGLIB_BLOOM(mask, ss[i+1]))
i = i + m;
}
}
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe:
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com