diff options
| author | Laurenz <laurmaedje@gmail.com> | 2023-04-13 14:23:46 +0200 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2023-04-13 14:23:46 +0200 |
| commit | 89cf4054d61d296245b34a20f9ad0b749c0f83e2 (patch) | |
| tree | 38aaae4cf2a5e4b5f67e59d499f652c2eb3a372a /src/model | |
| parent | f2732bb7b205361c5f309488b4e5235b4fc61e7c (diff) | |
Reduce amount of hashing
Diffstat (limited to 'src/model')
| -rw-r--r-- | src/model/content.rs | 24 | ||||
| -rw-r--r-- | src/model/styles.rs | 53 |
2 files changed, 35 insertions, 42 deletions
diff --git a/src/model/content.rs b/src/model/content.rs index 2ce12a51..fa189b11 100644 --- a/src/model/content.rs +++ b/src/model/content.rs @@ -3,7 +3,7 @@ use std::fmt::{self, Debug, Formatter, Write}; use std::iter::Sum; use std::ops::{Add, AddAssign}; -use comemo::Tracked; +use comemo::{Prehashed, Tracked}; use ecow::{eco_format, EcoString, EcoVec}; use super::{ @@ -29,8 +29,8 @@ pub struct Content { enum Attr { Span(Span), Field(EcoString), - Value(Value), - Child(Content), + Value(Prehashed<Value>), + Child(Prehashed<Content>), Styles(Styles), Prepared, Guard(Guard), @@ -54,9 +54,11 @@ impl Content { let Some(first) = iter.next() else { return Self::empty() }; let Some(second) = iter.next() else { return first }; let mut content = Content::empty(); - content.attrs.push(Attr::Child(first)); - content.attrs.push(Attr::Child(second)); - content.attrs.extend(iter.map(Attr::Child)); + content.attrs.push(Attr::Child(Prehashed::new(first))); + content.attrs.push(Attr::Child(Prehashed::new(second))); + content + .attrs + .extend(iter.map(|child| Attr::Child(Prehashed::new(child)))); content } @@ -164,10 +166,10 @@ impl Content { Attr::Field(field) => *field == name, _ => false, }) { - self.attrs.make_mut()[i + 1] = Attr::Value(value.into()); + self.attrs.make_mut()[i + 1] = Attr::Value(Prehashed::new(value.into())); } else { self.attrs.push(Attr::Field(name)); - self.attrs.push(Attr::Value(value.into())); + self.attrs.push(Attr::Value(Prehashed::new(value.into()))); } } @@ -285,7 +287,7 @@ impl Content { self } else { let mut content = Content::new(StyledElem::func()); - content.attrs.push(Attr::Child(self)); + content.attrs.push(Attr::Child(Prehashed::new(self))); content.attrs.push(Attr::Styles(styles)); content } @@ -466,11 +468,11 @@ impl Add for Content { lhs } (true, false) => { - lhs.attrs.push(Attr::Child(rhs)); + lhs.attrs.push(Attr::Child(Prehashed::new(rhs))); lhs } (false, true) => { - rhs.attrs.insert(0, Attr::Child(lhs)); + rhs.attrs.insert(0, Attr::Child(Prehashed::new(lhs))); rhs } (false, false) => Self::sequence([lhs, rhs]), diff --git a/src/model/styles.rs b/src/model/styles.rs index a841ca56..7fda52cf 100644 --- a/src/model/styles.rs +++ b/src/model/styles.rs @@ -2,8 +2,10 @@ use std::any::{Any, TypeId}; use std::fmt::{self, Debug, Formatter, Write}; use std::iter; use std::mem; +use std::ptr; use std::sync::Arc; +use comemo::Prehashed; use ecow::{eco_format, eco_vec, EcoString, EcoVec}; use super::{Content, ElemFunc, Element, Introspector, Label, Location, Vt}; @@ -15,7 +17,7 @@ use crate::util::pretty_array_like; /// A list of style properties. #[derive(Default, PartialEq, Clone, Hash)] -pub struct Styles(EcoVec<Style>); +pub struct Styles(EcoVec<Prehashed<Style>>); impl Styles { /// Create a new, empty style list. @@ -34,7 +36,7 @@ impl Styles { /// style map, `self` contributes the outer values and `value` is the inner /// one. pub fn set(&mut self, style: impl Into<Style>) { - self.0.push(style.into()); + self.0.push(Prehashed::new(style.into())); } /// Remove the style that was last set. @@ -51,20 +53,22 @@ impl Styles { /// Apply one outer styles. Like [`chain_one`](StyleChain::chain_one), but /// in-place. pub fn apply_one(&mut self, outer: Style) { - self.0.insert(0, outer); + self.0.insert(0, Prehashed::new(outer)); } /// Apply a slice of outer styles. - pub fn apply_slice(&mut self, outer: &[Style]) { + pub fn apply_slice(&mut self, outer: &[Prehashed<Style>]) { self.0 = outer.iter().cloned().chain(mem::take(self).0.into_iter()).collect(); } /// Add an origin span to all contained properties. pub fn spanned(mut self, span: Span) -> Self { for entry in self.0.make_mut() { - if let Style::Property(property) = entry { - property.span = Some(span); - } + entry.update(|entry| { + if let Style::Property(property) = entry { + property.span = Some(span); + } + }); } self } @@ -73,7 +77,7 @@ impl Styles { /// styles for the given element. pub fn interruption<T: Element>(&self) -> Option<Option<Span>> { let func = T::func(); - self.0.iter().find_map(|entry| match entry { + self.0.iter().find_map(|entry| match &**entry { Style::Property(property) => property.is_of(func).then_some(property.span), Style::Recipe(recipe) => recipe.is_of(func).then_some(Some(recipe.span)), }) @@ -82,7 +86,7 @@ impl Styles { impl From<Style> for Styles { fn from(entry: Style) -> Self { - Self(eco_vec![entry]) + Self(eco_vec![Prehashed::new(entry)]) } } @@ -566,7 +570,7 @@ cast_from_value! { #[derive(Default, Clone, Copy, Hash)] pub struct StyleChain<'a> { /// The first link of this chain. - head: &'a [Style], + head: &'a [Prehashed<Style>], /// The remaining links in the chain. tail: Option<&'a Self>, } @@ -590,14 +594,6 @@ impl<'a> StyleChain<'a> { } } - /// Make the given style the first link of the this chain. - pub fn chain_one<'b>(&'b self, style: &'b Style) -> StyleChain<'b> { - StyleChain { - head: std::slice::from_ref(style), - tail: Some(self), - } - } - /// Cast the first value for the given property in the chain. pub fn get<T: Cast>( self, @@ -733,16 +729,6 @@ impl<'a> StyleChain<'a> { fn pop(&mut self) { *self = self.tail.copied().unwrap_or_default(); } - - /// Whether two style chains contain the same pointers. - fn ptr_eq(self, other: Self) -> bool { - std::ptr::eq(self.head, other.head) - && match (self.tail, other.tail) { - (Some(a), Some(b)) => std::ptr::eq(a, b), - (None, None) => true, - _ => false, - } - } } impl Debug for StyleChain<'_> { @@ -756,13 +742,18 @@ impl Debug for StyleChain<'_> { impl PartialEq for StyleChain<'_> { fn eq(&self, other: &Self) -> bool { - self.ptr_eq(*other) || crate::util::hash128(self) == crate::util::hash128(other) + ptr::eq(self.head, other.head) + && match (self.tail, other.tail) { + (Some(a), Some(b)) => ptr::eq(a, b), + (None, None) => true, + _ => false, + } } } /// An iterator over the entries in a style chain. struct Entries<'a> { - inner: std::slice::Iter<'a, Style>, + inner: std::slice::Iter<'a, Prehashed<Style>>, links: Links<'a>, } @@ -787,7 +778,7 @@ impl<'a> Iterator for Entries<'a> { struct Links<'a>(Option<StyleChain<'a>>); impl<'a> Iterator for Links<'a> { - type Item = &'a [Style]; + type Item = &'a [Prehashed<Style>]; fn next(&mut self) -> Option<Self::Item> { let StyleChain { head, tail } = self.0?; |
