Skip to content

Commit 5a3aa2f

Browse files
committed
str: Improve .chars().count()
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.
1 parent b1da18f commit 5a3aa2f

File tree

2 files changed

+17
-0
lines changed

2 files changed

+17
-0
lines changed

src/libcollectionstest/str.rs

+1
Original file line numberDiff line numberDiff line change
@@ -767,6 +767,7 @@ fn test_iterator() {
767767
pos += 1;
768768
}
769769
assert_eq!(pos, v.len());
770+
assert_eq!(s.chars().count(), v.len());
770771
}
771772

772773
#[test]

src/libcore/str/mod.rs

+16
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,17 @@ impl<'a> Iterator for Chars<'a> {
424424
})
425425
}
426426

427+
#[inline]
428+
fn count(self) -> usize {
429+
// length in `char` is equal to the number of non-continuation bytes
430+
let bytes_len = self.iter.len();
431+
let mut cont_bytes = 0;
432+
for &byte in self.iter {
433+
cont_bytes += utf8_is_cont_byte(byte) as usize;
434+
}
435+
bytes_len - cont_bytes
436+
}
437+
427438
#[inline]
428439
fn size_hint(&self) -> (usize, Option<usize>) {
429440
let len = self.iter.len();
@@ -501,6 +512,11 @@ impl<'a> Iterator for CharIndices<'a> {
501512
}
502513
}
503514

515+
#[inline]
516+
fn count(self) -> usize {
517+
self.iter.count()
518+
}
519+
504520
#[inline]
505521
fn size_hint(&self) -> (usize, Option<usize>) {
506522
self.iter.size_hint()

0 commit comments

Comments
 (0)