diff options
author | Martin Fischer <martin@push-f.com> | 2023-08-16 12:00:29 +0200 |
---|---|---|
committer | Martin Fischer <martin@push-f.com> | 2023-08-19 13:41:55 +0200 |
commit | 180f6d6111b966627aa00a4017b6fb9751f7386c (patch) | |
tree | 4a0b638eebf352761da3425370ba3ac8dbad73c5 /src/emitter.rs | |
parent | 78c2066021deda483a4f0a1bb575543d98d27dca (diff) |
perf: only store start offsets for attribute spans
This spares us two usizes per AttrInternal<Range<usize>>.
So on a 64 bit target where a usize is 8 bytes this spares
us 16 bytes of memory per attribute (if spans are enabled,
... for Token<()> this obviously doesn't change anything).
And the DefaultEmitter now also no longer has to update the
spans on each Emitter::push_attribute_(name|value) call.
The spans are now calculated on demand by the Attribute methods,
which is fine since the assumption is that API users are only
interested in a few specific spans (rather than all spans).
Diffstat (limited to 'src/emitter.rs')
-rw-r--r-- | src/emitter.rs | 20 |
1 files changed, 10 insertions, 10 deletions
diff --git a/src/emitter.rs b/src/emitter.rs index 9dfb363..17a4882 100644 --- a/src/emitter.rs +++ b/src/emitter.rs @@ -205,7 +205,7 @@ impl<O> DefaultEmitter<O> { fn flush_current_attribute(&mut self) where - O: Clone, + O: Offset, { if let Some((name, map_val)) = self.current_attribute.take() { match self.current_token { @@ -213,14 +213,16 @@ impl<O> DefaultEmitter<O> { Entry::Vacant(vacant) => { vacant.insert(map_val); } - Entry::Occupied(_) => { - self.push_error(Error::DuplicateAttribute, map_val.name_span); + Entry::Occupied(entry) => { + let name_len = entry.key().len(); + self.push_error(Error::DuplicateAttribute, map_val.name_span(name_len)); } }, Some(Token::EndTag(_)) => { - self.attr_in_end_tag_span = Some(map_val.name_span.clone()); + let name_span = map_val.name_span(name.len()); + self.attr_in_end_tag_span = Some(name_span.clone()); if !self.seen_attributes.insert(name) { - self.push_error(Error::DuplicateAttribute, map_val.name_span); + self.push_error(Error::DuplicateAttribute, name_span); } } _ => { @@ -380,25 +382,23 @@ impl<O: Offset> Emitter<O> for DefaultEmitter<O> { self.current_attribute = Some(( String::new(), crate::attr::AttrInternal { - name_span: offset..offset, + name_offset: offset, value: String::new(), - value_span: Range::default(), + value_offset: O::default(), }, )); } fn init_attribute_value(&mut self, offset: O, _quoted: bool) { - self.current_attribute.as_mut().unwrap().1.value_span = offset..offset; + self.current_attribute.as_mut().unwrap().1.value_offset = offset; } fn push_attribute_name(&mut self, s: &str) { let current_attr = self.current_attribute.as_mut().unwrap(); current_attr.0.push_str(s); - current_attr.1.name_span.end += s.len(); } fn push_attribute_value(&mut self, s: &str) { let current_attr = self.current_attribute.as_mut().unwrap(); current_attr.1.value.push_str(s); - current_attr.1.value_span.end += s.len(); } fn set_doctype_public_identifier(&mut self, value: &str) { if let Some(Token::Doctype(Doctype { |