Custom PartialOrd makes ints slower


#1

Hey everyone!

I’m trying to process a bunch of integers with a reversed ordering (those are scores that should be sorted from largest to smallest):

#[derive(Clone, PartialEq, Eq, PartialOrd)]
struct Score(u32);

impl Ord for Score {
    fn cmp(&self, other: &Score) -> Ordering {
        other.0.cmp(&self.0)  // note reversed ordering
    }
}

I noticed that if instead of deriving PartialOrd I define it myself:

impl PartialOrd for Score {
    fn partial_cmp(&self, other: &Score) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

Processing becomes noticeably slower (x1.5 times). Why is that?

P.S. Working example


#2

PartialOrd has default methods for lt, le, ge and gt, which are relying on calling partial_cmp.

The implementations for numbers override those with specialised, faster variants.

So the solution in your case is providing them like this:

impl PartialOrd for Score {
    #[inline]
    fn partial_cmp(&self, other: &Score) -> Option<Ordering> {
        Some(self.cmp(other))
    }
    
    #[inline]
    fn lt(&self, other: &Score) -> bool { self.0 > other.0 }
    #[inline]
    fn le(&self, other: &Score) -> bool { self.0 >= other.0 }
    #[inline]
    fn ge(&self, other: &Score) -> bool { self.0 <= other.0 }
    #[inline]
    fn gt(&self, other: &Score) -> bool { self.0 < other.0 }
}

#3

That clears it up! Thank you!


#4

Just an FYI, there’s a Reverse<T> wrapper type in std::cmp which will do this order reversal for you.