style: Avoid quadratic time serialization of a declaration block.

At least when the longhands aren't custom properties.

We should also look into not serializing the style attribute eagerly when it's
not needed... But a lot of code currently rely on attribute values being
dereferenciables to &str, so that's harder to fix.

We should really look into all those vectors around too, but that's probably
less urgent.
This commit is contained in:
Emilio Cobos Álvarez 2017-06-14 11:40:49 +02:00
parent c6da6ba060
commit 8b20d7a982
No known key found for this signature in database
GPG key ID: 056B727BB9C1027C

View file

@ -590,7 +590,7 @@ impl ToCss for PropertyDeclarationBlock {
// Step 1 -> dest = result list
// Step 2
let mut already_serialized = Vec::new();
let mut already_serialized = PropertyDeclarationIdSet::new();
// Step 3
for &(ref declaration, importance) in &*self.declarations {
@ -598,7 +598,7 @@ impl ToCss for PropertyDeclarationBlock {
let property = declaration.id();
// Step 3.2
if already_serialized.contains(&property) {
if already_serialized.contains(property) {
continue;
}
@ -606,8 +606,10 @@ impl ToCss for PropertyDeclarationBlock {
let shorthands = declaration.shorthands();
if !shorthands.is_empty() {
// Step 3.3.1
//
// FIXME(emilio): All this looks terribly inefficient...
let mut longhands = self.declarations.iter()
.filter(|d| !already_serialized.contains(&d.0.id()))
.filter(|d| !already_serialized.contains(d.0.id()))
.collect::<Vec<_>>();
// Step 3.3.2
@ -642,10 +644,10 @@ impl ToCss for PropertyDeclarationBlock {
}
// Substep 1:
//
// Assuming that the PropertyDeclarationBlock contains no
// duplicate entries, if the current_longhands length is
// equal to the properties length, it means that the
// properties that map to shorthand are present in longhands
// Assuming that the PropertyDeclarationBlock contains no
// duplicate entries, if the current_longhands length is
// equal to the properties length, it means that the
// properties that map to shorthand are present in longhands
if current_longhands.len() != properties.len() {
continue;
}
@ -725,7 +727,7 @@ impl ToCss for PropertyDeclarationBlock {
for current_longhand in &current_longhands {
// Substep 9
already_serialized.push(current_longhand.id());
already_serialized.insert(current_longhand.id());
let index_to_remove = longhands.iter().position(|l| l.0 == **current_longhand);
if let Some(index) = index_to_remove {
// Substep 10
@ -736,7 +738,7 @@ impl ToCss for PropertyDeclarationBlock {
}
// Step 3.3.4
if already_serialized.contains(&property) {
if already_serialized.contains(property) {
continue;
}
@ -756,7 +758,7 @@ impl ToCss for PropertyDeclarationBlock {
&mut is_first_serialization)?;
// Step 3.3.8
already_serialized.push(property);
already_serialized.insert(property);
}
// Step 4