Skip to content

Commit

Permalink
Auto merge of #28436 - ranma42:faster-partialord, r=bluss
Browse files Browse the repository at this point in the history
This branch improves the performance of Ord and PartialOrd methods for slices compared to the iter-based implementation.
Based on the approach used in #26884.
  • Loading branch information
bors committed Sep 16, 2015
2 parents f18c2aa + 74dc146 commit 47d125d
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 23 deletions.
24 changes: 20 additions & 4 deletions src/libcore/cmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -463,17 +463,33 @@ mod impls {
}
}

partial_ord_impl! { char usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
partial_ord_impl! { f32 f64 }

macro_rules! ord_impl {
($($t:ty)*) => ($(
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialOrd for $t {
#[inline]
fn partial_cmp(&self, other: &$t) -> Option<Ordering> {
Some(self.cmp(other))
}
#[inline]
fn lt(&self, other: &$t) -> bool { (*self) < (*other) }
#[inline]
fn le(&self, other: &$t) -> bool { (*self) <= (*other) }
#[inline]
fn ge(&self, other: &$t) -> bool { (*self) >= (*other) }
#[inline]
fn gt(&self, other: &$t) -> bool { (*self) > (*other) }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Ord for $t {
#[inline]
fn cmp(&self, other: &$t) -> Ordering {
if *self < *other { Less }
else if *self > *other { Greater }
else { Equal }
if *self == *other { Equal }
else if *self < *other { Less }
else { Greater }
}
}
)*)
Expand Down
49 changes: 30 additions & 19 deletions src/libcore/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1559,30 +1559,41 @@ impl<T: Eq> Eq for [T] {}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Ord> Ord for [T] {
fn cmp(&self, other: &[T]) -> Ordering {
self.iter().cmp(other.iter())
let l = cmp::min(self.len(), other.len());

// Slice to the loop iteration range to enable bound check
// elimination in the compiler
let lhs = &self[..l];
let rhs = &other[..l];

for i in 0..l {
match lhs[i].cmp(&rhs[i]) {
Ordering::Equal => (),
non_eq => return non_eq,
}
}

self.len().cmp(&other.len())
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: PartialOrd> PartialOrd for [T] {
#[inline]
fn partial_cmp(&self, other: &[T]) -> Option<Ordering> {
self.iter().partial_cmp(other.iter())
}
#[inline]
fn lt(&self, other: &[T]) -> bool {
self.iter().lt(other.iter())
}
#[inline]
fn le(&self, other: &[T]) -> bool {
self.iter().le(other.iter())
}
#[inline]
fn ge(&self, other: &[T]) -> bool {
self.iter().ge(other.iter())
}
#[inline]
fn gt(&self, other: &[T]) -> bool {
self.iter().gt(other.iter())
let l = cmp::min(self.len(), other.len());

// Slice to the loop iteration range to enable bound check
// elimination in the compiler
let lhs = &self[..l];
let rhs = &other[..l];

for i in 0..l {
match lhs[i].partial_cmp(&rhs[i]) {
Some(Ordering::Equal) => (),
non_eq => return non_eq,
}
}

self.len().partial_cmp(&other.len())
}
}

0 comments on commit 47d125d

Please sign in to comment.