-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Implement StringPairs for efficient pairs(::AbstractString) #51631
Conversation
9fe3653
to
42170bf
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good to me and is a nice optimization.
Is this a better solution than #51671? |
See my comment here: #51631 (comment) |
Is there anything else that needs to be done here? FWIW, I profiled |
@vtjnash Could you give this another review? |
It sounds like someone still needs to investigate and fix the actual performance issue (#51631 (comment)) |
Okay, so I did two benchmarks. One simply measures the performance of function time_pairs(s::String)
n = 0
for (i, c) in pairs(s)
n = xor(n, reinterpret(UInt32, c) * i)
end
n
end
for source in ["en", "dk", "cn"]
src = read(source, String)
short = first(src, 20)
println(source, " long: ", @belapsed time_pairs($src))
println(source, " short: ", @belapsed time_pairs($short))
end With three difference sources: English (all ASCII), Danish (mostly ASCII) and Chinese (little ASCII). Results
And here, for a simple lstrip benchmark: bar(s) = sum(ncodeunits(lstrip(c -> reinterpret(UInt32, c) >>> 24 > 10, s)) for i in 1:10000000) This takes ~950 ms on #51671, and ~640 ms on #51671 + this PR
So, this PR is a clear win. |
Bump. What needs to be done to get this through? |
The default `pairs` will iterate keys and values separately. For strings, this represents double work, since both these iterations will need to determine valid string indices. The introduced StringPairs type will, whenever possible, only compute valid indices once. Currently, this is only optimised for `String` and `SubString{String}`, and not for `AbstractString`, nor is it optimised when reversed.
f08ac97
to
5f83be4
Compare
5f83be4
to
8d2699c
Compare
I've added "needs nanosoldier" because the noinline in string iteration may have unintended side effects. For example, it makes iteration of Cyrillic 2x slower and Chinese 1.6x slower. On the other hand, it allows iterate to inline itself so it will be faster for ASCII in many contexts. Just like the recent changes to nextind. So let's check its impact. |
@nanosoldier |
It may still be worthwhile for someone to figure out why this isn't handled in the compiler already (past analysis suggested it was a problem with the way it used the SubString constructor #51631 (comment)), but might as well take the win now |
Your benchmark job has completed, but no benchmarks were actually executed. Perhaps your tag predicate contains misspelled tags? cc @ |
@nanosoldier |
Your benchmark job has completed - possible performance regressions were detected. A full report can be found here. |
@DilumAluthge thanks for keeping this up to date. This is good to go now. |
Bump |
The default
pairs
will iterate keys and values separately. For strings, this represents double work, since both these iterations will need to determine valid string indices.The introduced StringPairs type will, whenever possible, only compute valid indices once.
Currently, this is only optimised for
String
andSubString{String}
, and not forAbstractString
, nor is it optimised when reversed.Simple benchmark:
Closes #51624