Skip to content

Commit

Permalink
feat: optimize character index storage in WithIndices (#85)
Browse files Browse the repository at this point in the history
* feat: optimize character index storage in WithIndices

* chore: cargo fmt

* fix: improve Source PartialEq perf
  • Loading branch information
SyMind authored Feb 1, 2024
1 parent 58cebc1 commit 3a9d872
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 15 deletions.
10 changes: 9 additions & 1 deletion src/source.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use std::{
any::Any,
any::{Any, TypeId},
borrow::Cow,
convert::{TryFrom, TryInto},
fmt,
Expand Down Expand Up @@ -110,6 +110,7 @@ impl<T: Any> AsAny for T {

pub trait DynEq {
fn dyn_eq(&self, other: &dyn Any) -> bool;
fn type_id(&self) -> TypeId;
}

impl<E: Eq + Any> DynEq for E {
Expand All @@ -120,10 +121,17 @@ impl<E: Eq + Any> DynEq for E {
false
}
}

fn type_id(&self) -> TypeId {
TypeId::of::<E>()
}
}

impl PartialEq for dyn Source {
fn eq(&self, other: &Self) -> bool {
if self.as_any().type_id() != other.as_any().type_id() {
return false;
}
self.dyn_eq(other.as_any())
}
}
Expand Down
23 changes: 9 additions & 14 deletions src/with_indices.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ 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: OnceCell<Box<[u32]>>,
pub indices_indexes: OnceCell<Vec<usize>>,
}

impl<T: AsRef<str>> WithIndices<T> {
Expand All @@ -23,24 +23,19 @@ 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 line = self.line.as_ref();
let indices_indexes = self
.indices_indexes
.get_or_init(|| line.char_indices().map(|(i, _)| i).collect::<Vec<_>>());

let str_len = self.line.as_ref().len() as u32;
let start = *indices_indexes.get(start_index).unwrap_or(&str_len) as usize;
let end = *indices_indexes.get(end_index).unwrap_or(&str_len) as usize;
let str_len = line.len();
let start = *indices_indexes.get(start_index).unwrap_or(&str_len);
let end = *indices_indexes.get(end_index).unwrap_or(&str_len);
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..end)
line.get_unchecked(start..end)
}
}
}
Expand Down

0 comments on commit 3a9d872

Please sign in to comment.