Skip to content

Commit

Permalink
Why is this faster? But hey, no more unsafe char around!
Browse files Browse the repository at this point in the history
This makes it take ~0.98ms (on my machine) to iterate all forwards
as opposed to ~1.2ms (on my machine).

Forward and Reverse iteration are now within margin of error
of each other, which means (hopefully) neither are getting an
optimization which is being denied to the other.

I still have no concrete idea why the reverse->filter_map
is ~20% faster than just the filter_map. My only guess is branch
prediction, which means it would be very CPU dependent.
  • Loading branch information
CAD97 committed Aug 13, 2017
1 parent 6c2d967 commit 7c0c5dc
Showing 1 changed file with 9 additions and 10 deletions.
19 changes: 9 additions & 10 deletions unic/char/range/src/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,6 @@ pub struct CharIter {
/// The lowest uniterated character (inclusive).
///
/// Iteration is finished if this is higher than `high`.
///
/// # Safety
///
/// This is not guaranteed to always be a valid character. Check before using!
/// Note that `high` _is_ guaranteed to be a valid character,
/// so this will always be a valid character when iteration is not yet finished.
low: char,

/// The highest uniterated character (inclusive).
Expand All @@ -39,16 +33,21 @@ impl From<CharIter> for CharRange {
impl CharIter {
#[inline]
#[allow(unsafe_code)]
// It is always safe to step `self.low` forward because
// `self.low` will only be used when less than `self.high`.
// When stepping `self.low` forward would go over `char::MAX`,
// Set `self.high` to `'\0'` instead. It will have the same effect --
// consuming the last element from the iterator and ending iteration.
fn step_forward(&mut self) {
self.low = unsafe { step::forward(self.low) }
if self.low == char::MAX {
self.high = '\0'
} else {
self.low = unsafe { step::forward(self.low) }
}
}

#[inline]
#[allow(unsafe_code)]
// When stepping `self.high` backward would cause underflow,
// step `self.low` forward instead. It will have the same effect --
// set `self.low` to `char::MAX` instead. It will have the same effect --
// consuming the last element from the iterator and ending iteration.
fn step_backward(&mut self) {
if self.high == '\0' {
Expand Down

0 comments on commit 7c0c5dc

Please sign in to comment.