Uh oh!
There was an error while loading. Please reload this page.
str::is_char_boundary - slight optimization - #84751
Conversation
rust-highfive
commented
Apr 30, 2021
r? @yaahc (rust-highfive has picked a reviewer for you, use r? to override) |
jyn514
commented
Apr 30, 2021
@Soveu fyi - A-codegen is usually used for the codegen part of the compiler itself, not for changes to the standard library that affect performance. |
Soveu
commented
Apr 30, 2021
btw, can I add |
jyn514
commented
Apr 30, 2021
You should be able to - try pinging rustbot with |
Soveu
commented
Apr 30, 2021
I was thinking all the time that only members can add those fancy red |
klensy
commented
Apr 30, 2021
Slightly less cryptic version https://godbolt.org/z/Y9o86ch6h pubfnis_char_boundary(s:&str,index:usize) -> bool{match s.as_bytes().get(index){None => false,Some(_)if index == 0 || index == s.len() => true,Some(&b) => (b asi8) >= -0x40,}}but this swaps order of cmp and test, better benchmark all versions to check actual difference. |
Soveu
commented
Apr 30, 2021
|
Upps pubfnis_char_boundary(s:&str,index:usize) -> bool{match s.as_bytes().get(index){Noneif index == s.len() => true,None => false,Some(_)if index == 0 => true,Some(&b) => (b asi8) >= -0x40,}}But this looks bad. |
Soveu
commented
Apr 30, 2021
I will soon add some comments |
Plus, I want to test how it affects |
Soveu
commented
Apr 30, 2021
Both on
|
klensy
commented
May 1, 2021
pubfnis_char_boundary(s:&str,index:usize) -> bool{if index == 0{true}elseif index < s.len(){unsafe{*s.as_bytes().get_unchecked(index)asi8 >= -0x40}}elseif index == s.len(){true}else{false}} |
Soveu
commented
May 12, 2021
@yaahc ? |
Amanieu
commented
May 14, 2021
@bors try @rust-timer queue |
rust-timer
commented
May 14, 2021
Awaiting bors try build completion. @rustbot label: +S-waiting-on-perf |
bors
commented
May 14, 2021
⌛ Trying commit 7bd9d9f with merge b8c3fd3abbd324a8ce3163e2d72ad2da5bb38d83... |
bors
commented
May 14, 2021
☀️ Try build successful - checks-actions |
rust-timer
commented
May 14, 2021
Queued b8c3fd3abbd324a8ce3163e2d72ad2da5bb38d83 with parent 69b352e, future comparison URL. |
rust-timer
commented
May 14, 2021
Finished benchmarking try commit (b8c3fd3abbd324a8ce3163e2d72ad2da5bb38d83): comparison url. Benchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. Please note that if the perf results are neutral, you should likely undo the rollup=never given below by specifying Importantly, though, if the results of this run are non-neutral do not roll this PR up -- it will mask other regressions or improvements in the roll up. @bors rollup=never |
Amanieu
commented
May 14, 2021
Perf changes seem to be in the noise. @bors r+ rollup=maybe |
bors
commented
May 14, 2021
📌 Commit 7bd9d9f has been approved by |
Soveu
commented
May 14, 2021
I was kinda expecting it, it's not a huge thing. What about binary size? |
…laumeGomez Rollup of 4 pull requests Successful merges: - rust-lang#84751 (str::is_char_boundary - slight optimization) - rust-lang#85185 (Generate not more docs than necessary) - rust-lang#85324 (Warn about unused `pub` fields in non-`pub` structs) - rust-lang#85329 (fix version_str comment) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
matthieu-m
commented
May 20, 2021
@klensy I'm surprised by those constructs:
Naively, I would expect to just return Is there any particular reason for the unusual branch? |
klensy
commented
May 21, 2021
All that |
Mark `str::is_char_boundary` and `str::split_at*` unstably `const`. Tracking issues: rust-lang#131516, rust-lang#131518 First commit implements `const_is_char_boundary`, second commit implements `const_str_split_at` (which depends on `const_is_char_boundary`) ~~I used `const_eval_select` for `is_char_boundary` since there is a comment about optimizations that would theoretically not happen with the simple `const`-compatible version (since `slice::get` is not `const`ifiable) cc rust-lang#84751. I have not checked if this code difference is still required for the optimization, so it might not be worth the code complication, but 🤷.~~ This changes `str::split_at_checked` to use a new private helper function `split_at_unchecked` (copied from `split_at_mut_unchecked`) that does pointer stuff instead of `get_unchecked`, since that is not currently `const`ifiable due to using the `SliceIndex` trait.
Rollup merge of rust-lang#131520 - zachs18:const-str-split, r=Noratrieb Mark `str::is_char_boundary` and `str::split_at*` unstably `const`. Tracking issues: rust-lang#131516, rust-lang#131518 First commit implements `const_is_char_boundary`, second commit implements `const_str_split_at` (which depends on `const_is_char_boundary`) ~~I used `const_eval_select` for `is_char_boundary` since there is a comment about optimizations that would theoretically not happen with the simple `const`-compatible version (since `slice::get` is not `const`ifiable) cc rust-lang#84751. I have not checked if this code difference is still required for the optimization, so it might not be worth the code complication, but 🤷.~~ This changes `str::split_at_checked` to use a new private helper function `split_at_unchecked` (copied from `split_at_mut_unchecked`) that does pointer stuff instead of `get_unchecked`, since that is not currently `const`ifiable due to using the `SliceIndex` trait.
Current
str::is_char_boundaryimplementation emits slightly more instructions, because it includes an additional branch forindex == s.len()Just changing the place of
index == s.len()merges it withindex < s.len()froms.as_bytes().get(index)This one has better codegen on every platform, except powerpc
x86 codegen
aarch64 codegen
riscv64gc codegen
example::is_char_boundary:
seqz a3, a2
xor a4, a1, a2
seqz a4, a4
or a4, a4, a3
addi a3, zero, 1
bnez a4, .LBB0_3
bgeu a2, a1, .LBB0_4
add a0, a0, a2
lb a0, 0(a0)
addi a1, zero, -65
slt a3, a1, a0
.LBB0_3:
mv a0, a3
ret
.LBB0_4:
mv a0, zero
ret
example::is_char_boundary2:
beqz a2, .LBB1_3
bgeu a2, a1, .LBB1_4
add a0, a0, a2
lb a0, 0(a0)
addi a1, zero, -65
slt a0, a1, a0
ret
.LBB1_3:
addi a0, zero, 1
ret
.LBB1_4:
xor a0, a1, a2
seqz a0, a0
ret
Link to godbolt
@rustbot label: A-codegen