Skip to content

Commit

Permalink
perf: WithIndices use OnceCell
Browse files Browse the repository at this point in the history
  • Loading branch information
jerrykingxyz committed Aug 31, 2023
1 parent cd63bee commit 66df67b
Showing 1 changed file with 19 additions and 13 deletions.
32 changes: 19 additions & 13 deletions src/with_indices.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
use std::cell::OnceCell;

#[derive(Debug, Clone)]
pub struct WithIndices<T: AsRef<str>> {
/// line is a string reference
pub line: T,
/// the byte position of each `char` in `line` string slice .
pub indices_indexes: Box<[u32]>,
pub indices_indexes: OnceCell<Box<[u32]>>,
}

impl<T: AsRef<str>> WithIndices<T> {
pub fn new(line: T) -> Self {
Self {
indices_indexes: line
.as_ref()
.char_indices()
.map(|(i, _)| i as u32)
.collect::<Vec<_>>()
.into_boxed_slice(),
indices_indexes: OnceCell::new(),
line,
}
}
Expand All @@ -26,17 +23,26 @@ impl<T: AsRef<str>> WithIndices<T> {
return "";
}

let indices_indexes = self.indices_indexes.get_or_init(|| {
self
.line
.as_ref()
.char_indices()
.map(|(i, _)| i as u32)
.collect::<Vec<_>>()
.into_boxed_slice()
});

let str_len = self.line.as_ref().len() as u32;
let start = *self.indices_indexes.get(start_index).unwrap_or(&str_len);
let end = *self.indices_indexes.get(end_index).unwrap_or(&str_len);
let start =
indices_indexes.get(start_index).unwrap_or(&str_len).clone() as usize;
let end =
indices_indexes.get(end_index).unwrap_or(&str_len).clone() as usize;
unsafe {
// SAFETY: Since `indices` iterates over the `CharIndices` of `self`, we can guarantee
// that the indices obtained from it will always be within the bounds of `self` and they
// will always lie on UTF-8 sequence boundaries.
self
.line
.as_ref()
.get_unchecked(start as usize..end as usize)
self.line.as_ref().get_unchecked(start..end)
}
}
}
Expand Down

0 comments on commit 66df67b

Please sign in to comment.