Skip to content

Commit cded89a

Browse files
committed
Auto merge of #30917 - arthurprs:bs_bounds_check, r=alexcrichton
Avoid bounds checking for binary search. All calculated indexes are safe and the branch is useless.
2 parents 8f36038 + 7e5b9d7 commit cded89a

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
@@ -294,22 +294,23 @@ impl<T> SliceExt for [T] {
294294
fn binary_search_by<F>(&self, mut f: F) -> Result<usize, usize> where
295295
F: FnMut(&T) -> Ordering
296296
{
297-
let mut base : usize = 0;
298-
let mut lim : usize = self.len();
297+
let mut base = 0usize;
298+
let mut s = self;
299299

300-
while lim != 0 {
301-
let ix = base + (lim >> 1);
302-
match f(&self[ix]) {
303-
Equal => return Ok(ix),
300+
loop {
301+
let (head, tail) = s.split_at(s.len() >> 1);
302+
if tail.is_empty() {
303+
return Err(base)
304+
}
305+
match f(&tail[0]) {
304306
Less => {
305-
base = ix + 1;
306-
lim -= 1;
307+
base += head.len() + 1;
308+
s = &tail[1..];
307309
}
308-
Greater => ()
310+
Greater => s = head,
311+
Equal => return Ok(base + head.len()),
309312
}
310-
lim >>= 1;
311313
}
312-
Err(base)
313314
}
314315

315316
#[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)