Skip to content

Commit a525266

Browse files
committed
perf: Avoid hashing in some cases
1 parent 07dbee6 commit a525266

File tree

6 files changed

+95
-3
lines changed

6 files changed

+95
-3
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
### Performance
66

77
- Use a simpler way for HTML tree traversal.
8+
- Avoid hashing in some cases.
89

910
## [0.10.0] - 2023-06-16
1011

bindings/python/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
### Performance
66

77
- Use a simpler way for HTML tree traversal.
8+
- Avoid hashing in some cases.
89

910
## [0.10.0] - 2023-06-16
1011

bindings/ruby/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
### Performance
66

77
- Use a simpler way for HTML tree traversal.
8+
- Avoid hashing in some cases.
89

910
## 0.10.0 - 2023-06-17
1011

bindings/wasm/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
### Performance
66

77
- Use a simpler way for HTML tree traversal.
8+
- Avoid hashing in some cases.
89

910
## [0.10.0] - 2023-06-16
1011

css-inline/src/hasher.rs

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
use core::hash::{BuildHasherDefault, Hasher};
2+
3+
pub(crate) type BuildNoHashHasher = BuildHasherDefault<NoHashHasher>;
4+
5+
#[derive(Default)]
6+
pub(crate) struct NoHashHasher(u64);
7+
8+
impl Hasher for NoHashHasher {
9+
fn finish(&self) -> u64 {
10+
self.0
11+
}
12+
13+
fn write(&mut self, _: &[u8]) {
14+
panic!("Should not happen")
15+
}
16+
fn write_u8(&mut self, n: u8) {
17+
self.0 = u64::from(n)
18+
}
19+
fn write_u16(&mut self, n: u16) {
20+
self.0 = u64::from(n)
21+
}
22+
fn write_u32(&mut self, n: u32) {
23+
self.0 = u64::from(n)
24+
}
25+
fn write_u64(&mut self, n: u64) {
26+
self.0 = n
27+
}
28+
29+
fn write_usize(&mut self, n: usize) {
30+
self.0 = n as u64
31+
}
32+
fn write_i8(&mut self, n: i8) {
33+
self.0 = n as u64
34+
}
35+
fn write_i16(&mut self, n: i16) {
36+
self.0 = n as u64
37+
}
38+
fn write_i32(&mut self, n: i32) {
39+
self.0 = n as u64
40+
}
41+
fn write_i64(&mut self, n: i64) {
42+
self.0 = n as u64
43+
}
44+
45+
fn write_isize(&mut self, n: isize) {
46+
self.0 = n as u64
47+
}
48+
}
49+
50+
#[cfg(test)]
51+
mod tests {
52+
use super::NoHashHasher;
53+
use std::hash::Hasher;
54+
55+
#[test]
56+
fn hasher() {
57+
let mut hasher = NoHashHasher::default();
58+
hasher.write_u8(42);
59+
assert_eq!(hasher.0, 42);
60+
hasher.write_u16(42);
61+
assert_eq!(hasher.0, 42);
62+
hasher.write_u32(42);
63+
assert_eq!(hasher.0, 42);
64+
hasher.write_u64(42);
65+
assert_eq!(hasher.0, 42);
66+
hasher.write_usize(42);
67+
assert_eq!(hasher.0, 42);
68+
hasher.write_i8(42);
69+
assert_eq!(hasher.0, 42);
70+
hasher.write_i16(42);
71+
assert_eq!(hasher.0, 42);
72+
hasher.write_i32(42);
73+
assert_eq!(hasher.0, 42);
74+
hasher.write_i64(42);
75+
assert_eq!(hasher.0, 42);
76+
hasher.write_isize(42);
77+
assert_eq!(hasher.0, 42);
78+
}
79+
80+
#[test]
81+
#[should_panic]
82+
fn test_panic() {
83+
let mut hasher = NoHashHasher::default();
84+
hasher.write(b"a");
85+
}
86+
}

css-inline/src/lib.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
)]
2727

2828
pub mod error;
29+
mod hasher;
2930
mod html;
3031
mod parser;
3132

@@ -39,7 +40,8 @@ use std::{
3940
io::{ErrorKind, Write},
4041
};
4142

42-
use crate::html::{Document, NodeId, Specificity};
43+
use hasher::BuildNoHashHasher;
44+
use html::{Document, NodeId, Specificity};
4345
pub use url::{ParseError, Url};
4446

4547
/// Replace double quotes in property values.
@@ -232,7 +234,7 @@ impl<'a> CSSInliner<'a> {
232234
// selector's specificity. When two rules overlap on the same declaration, then
233235
// the one with higher specificity replaces another.
234236
// 2. Resulting styles are merged into existing "style" tags.
235-
let mut styles = IndexMap::with_capacity(128);
237+
let mut styles = IndexMap::with_capacity_and_hasher(128, BuildNoHashHasher::default());
236238
for style in document.styles() {
237239
process_css(&document, style, &mut styles);
238240
}
@@ -338,7 +340,7 @@ fn load_external(location: &str) -> Result<String> {
338340
fn process_css(
339341
document: &Document,
340342
css: &str,
341-
styles: &mut IndexMap<NodeId, IndexMap<String, (Specificity, String)>>,
343+
styles: &mut IndexMap<NodeId, IndexMap<String, (Specificity, String)>, BuildNoHashHasher>,
342344
) {
343345
let mut parse_input = cssparser::ParserInput::new(css);
344346
let mut parser = cssparser::Parser::new(&mut parse_input);

0 commit comments

Comments
 (0)