diff options
| author | Krishna Sai Veera Reddy <krishnasai.veerareddy@gm.com> | 2019-11-29 15:22:44 -0700 |
|---|---|---|
| committer | Krishna Sai Veera Reddy <krishnasai.veerareddy@gm.com> | 2019-11-29 15:22:44 -0700 |
| commit | 4ca769ad091ef0018f5a20effaf4b4f428a034d7 (patch) | |
| tree | d389a56e4d6ab7d9a93d325008259702f4095e38 /src/libcore | |
| parent | d99e0c6d02b159f305474f58c8c38027bb06e051 (diff) | |
| download | rust-4ca769ad091ef0018f5a20effaf4b4f428a034d7.tar.gz rust-4ca769ad091ef0018f5a20effaf4b4f428a034d7.zip | |
Optimize Ord trait implementation for bool
Casting the booleans to `i8`s and converting their difference into `Ordering` generates better assembly than casting them to `u8`s and comparing them.
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/cmp.rs | 11 | ||||
| -rw-r--r-- | src/libcore/tests/cmp.rs | 8 |
2 files changed, 18 insertions, 1 deletions
diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index eea3dc39d34..e72b6117ba8 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -1006,6 +1006,7 @@ pub fn max_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T { // Implementation of PartialEq, Eq, PartialOrd and Ord for primitive types mod impls { + use crate::hint::unreachable_unchecked; use crate::cmp::Ordering::{self, Less, Greater, Equal}; macro_rules! partial_eq_impl { @@ -1126,7 +1127,15 @@ mod impls { impl Ord for bool { #[inline] fn cmp(&self, other: &bool) -> Ordering { - (*self as u8).cmp(&(*other as u8)) + // Casting to i8's and converting the difference to an Ordering generates + // more optimal assembly. + // See <https://github.com/rust-lang/rust/issues/66780> for more info. + match (*self as i8) - (*other as i8) { + -1 => Less, + 0 => Equal, + 1 => Greater, + _ => unsafe { unreachable_unchecked() }, + } } } diff --git a/src/libcore/tests/cmp.rs b/src/libcore/tests/cmp.rs index 5e6778e222a..56a2f4acf6e 100644 --- a/src/libcore/tests/cmp.rs +++ b/src/libcore/tests/cmp.rs @@ -10,6 +10,14 @@ fn test_int_totalord() { } #[test] +fn test_bool_totalord() { + assert_eq!(true.cmp(&false), Greater); + assert_eq!(false.cmp(&true), Less); + assert_eq!(true.cmp(&true), Equal); + assert_eq!(false.cmp(&false), Equal); +} + +#[test] fn test_mut_int_totalord() { assert_eq!((&mut 5).cmp(&&mut 10), Less); assert_eq!((&mut 10).cmp(&&mut 5), Greater); |
