]> git.lizzy.rs Git - rust.git/commitdiff
Improve PartialEq for slices
authorBjörn Steinbrink <bsteinbr@gmail.com>
Wed, 8 Jul 2015 12:49:55 +0000 (14:49 +0200)
committerBjörn Steinbrink <bsteinbr@gmail.com>
Wed, 8 Jul 2015 12:49:55 +0000 (14:49 +0200)
Exploiting the fact that getting the length of the slices is known, we
can use a counted loop instead of iterators, which means that we only
need a single counter, instead of having to increment and check one
pointer for each iterator.

Benchmarks comparing vectors with 100,000 elements:

Before:

```
running 8 tests
test eq1_u8  ... bench:      66,757 ns/iter (+/- 113)
test eq2_u16 ... bench:     111,267 ns/iter (+/- 149)
test eq3_u32 ... bench:     126,282 ns/iter (+/- 111)
test eq4_u64 ... bench:     126,418 ns/iter (+/- 155)
test ne1_u8  ... bench:      88,990 ns/iter (+/- 161)
test ne2_u16 ... bench:      89,126 ns/iter (+/- 265)
test ne3_u32 ... bench:      96,901 ns/iter (+/- 92)
test ne4_u64 ... bench:      96,750 ns/iter (+/- 137)
```

After:

```
running 8 tests
test eq1_u8  ... bench:      46,413 ns/iter (+/- 521)
test eq2_u16 ... bench:      46,500 ns/iter (+/- 74)
test eq3_u32 ... bench:      50,059 ns/iter (+/- 92)
test eq4_u64 ... bench:      54,001 ns/iter (+/- 92)
test ne1_u8  ... bench:      47,595 ns/iter (+/- 53)
test ne2_u16 ... bench:      47,521 ns/iter (+/- 59)
test ne3_u32 ... bench:      44,889 ns/iter (+/- 74)
test ne4_u64 ... bench:      47,775 ns/iter (+/- 68)
```

src/libcore/slice.rs

index a8c995f37cce44cb84bcb5bf86bfeff447d159cc..78cda8c2c7204b7d637fd34d76eb48f4ea9d4003 100644 (file)
@@ -1459,12 +1459,30 @@ pub fn copy_memory(src: &[u8], dst: &mut [u8]) {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<A, B> PartialEq<[B]> for [A] where A: PartialEq<B> {
     fn eq(&self, other: &[B]) -> bool {
-        self.len() == other.len() &&
-            order::eq(self.iter(), other.iter())
+        if self.len() != other.len() {
+            return false;
+        }
+
+        for i in 0..self.len() {
+            if !self[i].eq(&other[i]) {
+                return false;
+            }
+        }
+
+        true
     }
     fn ne(&self, other: &[B]) -> bool {
-        self.len() != other.len() ||
-            order::ne(self.iter(), other.iter())
+        if self.len() != other.len() {
+            return true;
+        }
+
+        for i in 0..self.len() {
+            if self[i].ne(&other[i]) {
+                return true;
+            }
+        }
+
+        false
     }
 }