Skip to content

Commit 7e5b9d7

Browse files
committed
Avoid bounds check for slice binary search
1 parent e5bab5d commit 7e5b9d7

File tree

2 files changed

+13
-16
lines changed

2 files changed

+13
-16
lines changed

src/libcore/slice.rs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -295,22 +295,23 @@ impl<T> SliceExt for [T] {
295295
fn binary_search_by<F>(&self, mut f: F) -> Result<usize, usize> where
296296
F: FnMut(&T) -> Ordering
297297
{
298-
let mut base : usize = 0;
299-
let mut lim : usize = self.len();
298+
let mut base = 0usize;
299+
let mut s = self;
300300

301-
while lim != 0 {
302-
let ix = base + (lim >> 1);
303-
match f(&self[ix]) {
304-
Equal => return Ok(ix),
301+
loop {
302+
let (head, tail) = s.split_at(s.len() >> 1);
303+
if tail.is_empty() {
304+
return Err(base)
305+
}
306+
match f(&tail[0]) {
305307
Less => {
306-
base = ix + 1;
307-
lim -= 1;
308+
base += head.len() + 1;
309+
s = &tail[1..];
308310
}
309-
Greater => ()
311+
Greater => s = head,
312+
Equal => return Ok(base + head.len()),
310313
}
311-
lim >>= 1;
312314
}
313-
Err(base)
314315
}
315316

316317
#[inline]

src/libcoretest/slice.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,24 +11,20 @@
1111
use core::result::Result::{Ok, Err};
1212

1313
#[test]
14-
fn binary_search_not_found() {
14+
fn test_binary_search() {
1515
let b = [1, 2, 4, 6, 8, 9];
1616
assert!(b.binary_search_by(|v| v.cmp(&6)) == Ok(3));
17-
let b = [1, 2, 4, 6, 8, 9];
1817
assert!(b.binary_search_by(|v| v.cmp(&5)) == Err(3));
1918
let b = [1, 2, 4, 6, 7, 8, 9];
2019
assert!(b.binary_search_by(|v| v.cmp(&6)) == Ok(3));
21-
let b = [1, 2, 4, 6, 7, 8, 9];
2220
assert!(b.binary_search_by(|v| v.cmp(&5)) == Err(3));
2321
let b = [1, 2, 4, 6, 8, 9];
2422
assert!(b.binary_search_by(|v| v.cmp(&8)) == Ok(4));
25-
let b = [1, 2, 4, 6, 8, 9];
2623
assert!(b.binary_search_by(|v| v.cmp(&7)) == Err(4));
2724
let b = [1, 2, 4, 6, 7, 8, 9];
2825
assert!(b.binary_search_by(|v| v.cmp(&8)) == Ok(5));
2926
let b = [1, 2, 4, 5, 6, 8, 9];
3027
assert!(b.binary_search_by(|v| v.cmp(&7)) == Err(5));
31-
let b = [1, 2, 4, 5, 6, 8, 9];
3228
assert!(b.binary_search_by(|v| v.cmp(&0)) == Err(0));
3329
let b = [1, 2, 4, 5, 6, 8];
3430
assert!(b.binary_search_by(|v| v.cmp(&9)) == Err(6));

0 commit comments

Comments
 (0)