Open Pzixel opened 2 years ago
The solution is to add refinement typing in Rust: https://antelang.org/docs/language/#refinement-types
Well while refinement types are great I think rust may just go with what is already supported. For example if we replace Err
with Ok
then it can see that index is no bigger than a.len()
and removes the assert_failed
. It just about implementing a bit more sophisticated heuristics.
Well, refinement typing is a more general solution, you can use for much more than this case of binary_search :)
Have you benchmarked this? Inserting in the middle of a vec incurs O(n) cost for the shifting, that likely dwarves the cost of the bounds check so the optimization may not be worth it.
Well right, but inserting in the end of a vec incurs no costs for the shifting. I can also imagine this might come with some unexpected benefits in other functions and/or scenarios.
I've got a PR open that might improve this: #102535
(It'll definitely help for some slice methods, but I'm unsure about Vec
ones, since the bounds checking is more complicated when Deref
is involved.)
@rustbot label +A-llvm +I-slow
Looks like the call to insert::assert_failed
is still there
Consider following function:
On current rust 1.61.0 you can expect following output:
It would be nice to have some attribute or other way of saying that binary search is always returning a valid insert index and bounds check should be eliminated. You can get an expected output in current rustc versions via:
Since performing a search and then inserting is one of main
binary_search
use cases it might be worthwhile to implement such an optimization. See godbolt link for a whole example