-
-
Notifications
You must be signed in to change notification settings - Fork 31.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Avoid redundant allocations in str.find and like #67761
Comments
Currently str.find() and similar methods can make a copy of self or searched string if they have different kinds. In some cases this is redundant because the result can be known before trying to search. Longer string can't be found in shorter string and wider string can't be found in narrower string. Proposed patch avoid creating temporary widened copies in such corner cases. It also adds special cases for searching 1-character strings. Some sample microbenchmark results: $ ./python -m timeit -s "a = 'x'; b = 'x\U00012345'" -- "b.find(a)"
Unpatched: 1000000 loops, best of 3: 1.92 usec per loop
Patched: 1000000 loops, best of 3: 1.03 usec per loop
$ ./python -m timeit -s "a = 'x'; b = 'x\U00012345'" -- "a in b"
Unpatched: 1000000 loops, best of 3: 0.543 usec per loop
Patched: 1000000 loops, best of 3: 0.25 usec per loop
$ ./python -m timeit -s "a = '\U00012345'; b = 'x'*1000" -- "b.find(a)"
Unpatched: 100000 loops, best of 3: 4.58 usec per loop
Patched: 1000000 loops, best of 3: 0.969 usec per loop
$ ./python -m timeit -s "a = 'x'*1000; b = '\U00012345'" -- "b.find(a)"
Unpatched: 100000 loops, best of 3: 3.77 usec per loop
Patched: 1000000 loops, best of 3: 0.97 usec per loop
$ ./python -m timeit -s "a = 'x'*1000; b = '\U00012345'" -- "a in b"
Unpatched: 100000 loops, best of 3: 2.4 usec per loop
Patched: 1000000 loops, best of 3: 0.225 usec per loop |
New changeset 6db9d7c1be29 by Serhiy Storchaka in branch 'default': |
Looks as this patch makes buildbots crash. |
Yep. It took me some minutes to find that the crash was caused by this issue :-p ... Current thread 0x000010ec (most recent call first): |
The problem is that Windows has no memrchr() function, and so fastsearch_memchr_1char() only supports FAST_SEARCH on Windows. |
New changeset 3ac58de829ef by Victor Stinner in branch 'default': |
It looks like fastsearch_memchr_1char() manipulate pointers for memory alignment. It's not necessary when looking for ASCII or Latin1 characters or for bytes. I propose to add a new fastsearch_memchr_1byte() function which would be used by bytes and bytearray, but also by str for ASCII and Latin1 strings. Are you interested to implement this idea Serhiy? For Windows without memrchr(), the code can be a simple loop. |
Many thanks Victor for fixing crashes. Unfortunately I couldn't reproduce a Yes, I'll look how the code can be optimized. |
Here is a patch that restores optimization of bytes.rfind() and bytearray.rfind() with 1-byte argument on Linux (it also reverts bc1a178b3bc8). |
New changeset 311a4d28631b by Serhiy Storchaka in branch '3.5': New changeset c06410c68217 by Serhiy Storchaka in branch 'default': |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: