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 Sep 5, 2023
1 parent cd63bee commit 51b1532
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 once_cell::sync::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

1 comment on commit 51b1532

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark

Benchmark suite Current: 51b1532 Previous: d9ff439 Ratio
benchmark_concat_generate_base64 24224 ns/iter (± 170) 29541 ns/iter (± 516) 0.82
benchmark_concat_generate_base64_with_cache 15135 ns/iter (± 95) 19886 ns/iter (± 286) 0.76
benchmark_concat_generate_string 12394 ns/iter (± 67) 13541 ns/iter (± 1450) 0.92
benchmark_concat_generate_string_with_cache 3466 ns/iter (± 15) 4103 ns/iter (± 138) 0.84

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.