Avoid bounds check for slice binary search
This commit is contained in:
parent
e5bab5dd00
commit
7e5b9d7213
@ -295,22 +295,23 @@ impl<T> SliceExt for [T] {
|
||||
fn binary_search_by<F>(&self, mut f: F) -> Result<usize, usize> where
|
||||
F: FnMut(&T) -> Ordering
|
||||
{
|
||||
let mut base : usize = 0;
|
||||
let mut lim : usize = self.len();
|
||||
let mut base = 0usize;
|
||||
let mut s = self;
|
||||
|
||||
while lim != 0 {
|
||||
let ix = base + (lim >> 1);
|
||||
match f(&self[ix]) {
|
||||
Equal => return Ok(ix),
|
||||
Less => {
|
||||
base = ix + 1;
|
||||
lim -= 1;
|
||||
}
|
||||
Greater => ()
|
||||
loop {
|
||||
let (head, tail) = s.split_at(s.len() >> 1);
|
||||
if tail.is_empty() {
|
||||
return Err(base)
|
||||
}
|
||||
match f(&tail[0]) {
|
||||
Less => {
|
||||
base += head.len() + 1;
|
||||
s = &tail[1..];
|
||||
}
|
||||
Greater => s = head,
|
||||
Equal => return Ok(base + head.len()),
|
||||
}
|
||||
lim >>= 1;
|
||||
}
|
||||
Err(base)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -11,24 +11,20 @@
|
||||
use core::result::Result::{Ok, Err};
|
||||
|
||||
#[test]
|
||||
fn binary_search_not_found() {
|
||||
fn test_binary_search() {
|
||||
let b = [1, 2, 4, 6, 8, 9];
|
||||
assert!(b.binary_search_by(|v| v.cmp(&6)) == Ok(3));
|
||||
let b = [1, 2, 4, 6, 8, 9];
|
||||
assert!(b.binary_search_by(|v| v.cmp(&5)) == Err(3));
|
||||
let b = [1, 2, 4, 6, 7, 8, 9];
|
||||
assert!(b.binary_search_by(|v| v.cmp(&6)) == Ok(3));
|
||||
let b = [1, 2, 4, 6, 7, 8, 9];
|
||||
assert!(b.binary_search_by(|v| v.cmp(&5)) == Err(3));
|
||||
let b = [1, 2, 4, 6, 8, 9];
|
||||
assert!(b.binary_search_by(|v| v.cmp(&8)) == Ok(4));
|
||||
let b = [1, 2, 4, 6, 8, 9];
|
||||
assert!(b.binary_search_by(|v| v.cmp(&7)) == Err(4));
|
||||
let b = [1, 2, 4, 6, 7, 8, 9];
|
||||
assert!(b.binary_search_by(|v| v.cmp(&8)) == Ok(5));
|
||||
let b = [1, 2, 4, 5, 6, 8, 9];
|
||||
assert!(b.binary_search_by(|v| v.cmp(&7)) == Err(5));
|
||||
let b = [1, 2, 4, 5, 6, 8, 9];
|
||||
assert!(b.binary_search_by(|v| v.cmp(&0)) == Err(0));
|
||||
let b = [1, 2, 4, 5, 6, 8];
|
||||
assert!(b.binary_search_by(|v| v.cmp(&9)) == Err(6));
|
||||
|
Loading…
Reference in New Issue
Block a user