-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
Refactor char/string and byte search #54667
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
Conversation
df9c1d8
to
ba4e410
Compare
This is good to go now. Test failures are unrelated. |
0b08a60
to
c1f87e0
Compare
Bump. CI failures are unrelated. |
ec0ef94
to
39a6449
Compare
Bump |
@nanosoldier |
@nanosoldier |
The perf results here look great! We really should try to get this reviewed and merged ASAP |
Your benchmark job has completed - possible performance regressions were detected. A full report can be found here. |
In text, the first UTF8 bytes of characters are typically more repetitive than the last byte. For example, most Greek characters start with 0xce or 0xcf. By searching for the more unique last byte, more time is spent in the memchr fast path. This gives a significant speedup.
It's more Julian to return nothing directly from the search function.
Many of these are identical to the generic fallback
This has two advantages: First, it consolidates the implementation of findnext and findall. Second, it allows a hypothetical lazy findall iterator to be trivially implemented later.
The search functions are a basic building block of the other functions, and may e.g. be called in a loop. It's wasteful to check bounds in these, as they are often called when we know for sure we are inbounds. Move the boundscheck closer to the top-level calls. This should slightly improve efficiency.
Take fast path not in every iteration, but just once, outside the loop.
7511e93
to
a5fbc1f
Compare
Nanosoldier found a regression for short ASCII searches, where extra book-keeping in this PR, which speeds up the special cases, but costs around 5 nanoseconds, becomes significant. I've addressed this by manually adding a fast path in |
@nanosoldier |
Your benchmark job has completed - possible performance regressions were detected. A full report can be found here. |
I think this is good to go, but I do want someone else to get another set of eyes on this. |
Just PkgEval it and if it looks good, merge? |
@nanosoldier |
The package evaluation job you requested has completed - possible new issues were detected. Report summary❗ Packages that crashed2 packages crashed only on the current version.
13 packages crashed on the previous version too. ✖ Packages that failed16 packages failed only on the current version.
1111 packages failed on the previous version too. ✔ Packages that passed tests30 packages passed tests only on the current version.
5325 packages passed tests on the previous version too. ~ Packages that at least loaded20 packages successfully loaded only on the current version.
2935 packages successfully loaded on the previous version too. ➖ Packages that were skipped altogether908 packages were skipped on the previous version too. |
This is a refactoring of
base/string/search.jl
. It is purely internal, and comes with no changes in behaviour. It's based on #54593 and #54579, so those needs to get merged first, then this PR will be rebased onto master.Included changes are:
_search
and_rsearch
functions to the outer top-level functions that call them. This is because the former may be called in a loop where repeated boundschecking is needless. This should speed up search a bit.findall
andfindnext
to share implementation, and will also make it trivially easy to implement a lazy findall in the future (see Implement lazyfindall
(Iterators.findall
, perhaps?) #43737)IMO there is still more work to be done on this file, but this requires a decision to be made on #43737, #54581 or #54584
Benchmarks
1.11.0-beta2:
This PR: