about summary refs log tree commit diff
path: root/src/libcore/str
diff options
context:
space:
mode:
authorUlrik Sverdrup <bluss@users.noreply.github.com>2016-04-05 14:06:20 +0200
committerUlrik Sverdrup <bluss@users.noreply.github.com>2016-04-05 14:06:20 +0200
commit5d56e1daed3aab8149ecbf69baf5bc1785f08627 (patch)
tree2d86430d73b671e5b2ccd494278490130645cc6c /src/libcore/str
parenta09f386e8d1c31133f0ce1123fbeaedcff40a77d (diff)
Specialize equality for [T] and comparison for [u8]
Where T is a type that can be compared for equality bytewise, we can use
memcmp. We can also use memcmp for PartialOrd, Ord for [u8] and by
extension &str.

This is an improvement for example for the comparison [u8] == [u8] that
used to emit a loop that compared the slices byte by byte.

One worry here could be that this introduces function calls to memcmp
in contexts where it should really inline the comparison or even
optimize it out, but llvm takes care of recognizing memcmp specifically.
Diffstat (limited to 'src/libcore/str')
-rw-r--r--src/libcore/str/mod.rs25
1 files changed, 3 insertions, 22 deletions
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index d5a5e2b4741..305546df5be 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -1150,16 +1150,7 @@ Section: Comparing strings
 #[lang = "str_eq"]
 #[inline]
 fn eq_slice(a: &str, b: &str) -> bool {
-    a.len() == b.len() && unsafe { cmp_slice(a, b, a.len()) == 0 }
-}
-
-/// Bytewise slice comparison.
-/// NOTE: This uses the system's memcmp, which is currently dramatically
-/// faster than comparing each byte in a loop.
-#[inline]
-unsafe fn cmp_slice(a: &str, b: &str, len: usize) -> i32 {
-    extern { fn memcmp(s1: *const i8, s2: *const i8, n: usize) -> i32; }
-    memcmp(a.as_ptr() as *const i8, b.as_ptr() as *const i8, len)
+    a.as_bytes() == b.as_bytes()
 }
 
 /*
@@ -1328,8 +1319,7 @@ Section: Trait implementations
 */
 
 mod traits {
-    use cmp::{self, Ordering, Ord, PartialEq, PartialOrd, Eq};
-    use cmp::Ordering::{Less, Greater};
+    use cmp::{Ord, Ordering, PartialEq, PartialOrd, Eq};
     use iter::Iterator;
     use option::Option;
     use option::Option::Some;
@@ -1340,16 +1330,7 @@ mod traits {
     impl Ord for str {
         #[inline]
         fn cmp(&self, other: &str) -> Ordering {
-            let cmp = unsafe {
-                super::cmp_slice(self, other, cmp::min(self.len(), other.len()))
-            };
-            if cmp == 0 {
-                self.len().cmp(&other.len())
-            } else if cmp < 0 {
-                Less
-            } else {
-                Greater
-            }
+            self.as_bytes().cmp(other.as_bytes())
         }
     }