]> git.lizzy.rs Git - rust.git/commitdiff
str: Improve .chars().count()
authorUlrik Sverdrup <bluss@users.noreply.github.com>
Sat, 19 Nov 2016 22:18:43 +0000 (23:18 +0100)
committerUlrik Sverdrup <bluss@users.noreply.github.com>
Sat, 19 Nov 2016 22:46:39 +0000 (23:46 +0100)
Use a simpler loop to count the `char` of a string: count the
number of non-continuation bytes. Use `count += <conditional>` which the
compiler understands well and can apply loop optimizations to.

src/libcollectionstest/str.rs
src/libcore/str/mod.rs

index cc56bbf4890aa46de435ab3048d1952aeaaa7e18..c7efd4ab2b1256451f235e9fbdfe34452d3171e8 100644 (file)
@@ -767,6 +767,7 @@ fn test_iterator() {
         pos += 1;
     }
     assert_eq!(pos, v.len());
+    assert_eq!(s.chars().count(), v.len());
 }
 
 #[test]
index 196750254af30eacadeb20f8594a0208dc319f92..7f91da5314247d104066b4289b4ba41578510bed 100644 (file)
@@ -424,6 +424,17 @@ fn next(&mut self) -> Option<char> {
         })
     }
 
+    #[inline]
+    fn count(self) -> usize {
+        // length in `char` is equal to the number of non-continuation bytes
+        let bytes_len = self.iter.len();
+        let mut cont_bytes = 0;
+        for &byte in self.iter {
+            cont_bytes += utf8_is_cont_byte(byte) as usize;
+        }
+        bytes_len - cont_bytes
+    }
+
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
         let len = self.iter.len();
@@ -501,6 +512,11 @@ fn next(&mut self) -> Option<(usize, char)> {
         }
     }
 
+    #[inline]
+    fn count(self) -> usize {
+        self.iter.count()
+    }
+
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.iter.size_hint()