diff options
| author | bors <bors@rust-lang.org> | 2016-01-22 19:00:15 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2016-01-22 19:00:15 +0000 |
| commit | cded89a3d167a1b736669223ee1ddc1c0744d8d9 (patch) | |
| tree | 0da916c67451eacf8d7f58c7a34c9a88a2b7dfab | |
| parent | 8f36038490559a98efcba3521564663b15785d9c (diff) | |
| parent | 7e5b9d721315611be82cc4a1f9c0e895c90b6348 (diff) | |
| download | rust-cded89a3d167a1b736669223ee1ddc1c0744d8d9.tar.gz rust-cded89a3d167a1b736669223ee1ddc1c0744d8d9.zip | |
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.
| -rw-r--r-- | src/libcore/slice.rs | 23 | ||||
| -rw-r--r-- | src/libcoretest/slice.rs | 6 |
2 files changed, 13 insertions, 16 deletions
diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index 6107564b4ae..40041c748e7 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -294,22 +294,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), + loop { + let (head, tail) = s.split_at(s.len() >> 1); + if tail.is_empty() { + return Err(base) + } + match f(&tail[0]) { Less => { - base = ix + 1; - lim -= 1; + base += head.len() + 1; + s = &tail[1..]; } - Greater => () + Greater => s = head, + Equal => return Ok(base + head.len()), } - lim >>= 1; } - Err(base) } #[inline] diff --git a/src/libcoretest/slice.rs b/src/libcoretest/slice.rs index d60eeb76ccd..f82ab44adad 100644 --- a/src/libcoretest/slice.rs +++ b/src/libcoretest/slice.rs @@ -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)); |
