From cbe4ba60c3c7e87af4b1659adf2e848eb7a0dfba Mon Sep 17 00:00:00 2001 From: Aliaksandr Kalenik Date: Sun, 27 Jul 2025 23:28:34 +0200 Subject: [PATCH] LibWeb: Implement faster `equals()` for UnresolvedStyleValue Compare `Vector` directly instead of serializing them into strings first. This is required for the upcoming changes where we would compare previous and new sets of custom properties to figure out whether we need to invalidate descendant elements. Without this change `equals()` would show up being hot in profiles. --- Libraries/LibWeb/CSS/Parser/ComponentValue.h | 2 ++ Libraries/LibWeb/CSS/Parser/Token.h | 5 +++++ Libraries/LibWeb/CSS/Parser/Types.h | 6 ++++++ Libraries/LibWeb/CSS/StyleValues/UnresolvedStyleValue.cpp | 3 +-- 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/Libraries/LibWeb/CSS/Parser/ComponentValue.h b/Libraries/LibWeb/CSS/Parser/ComponentValue.h index e05e90bdf67..b86c96e80ab 100644 --- a/Libraries/LibWeb/CSS/Parser/ComponentValue.h +++ b/Libraries/LibWeb/CSS/Parser/ComponentValue.h @@ -48,6 +48,8 @@ public: String to_debug_string() const; String original_source_text() const; + bool operator==(ComponentValue const&) const = default; + private: Variant m_value; }; diff --git a/Libraries/LibWeb/CSS/Parser/Token.h b/Libraries/LibWeb/CSS/Parser/Token.h index 98d1c40a815..a01b5ae7034 100644 --- a/Libraries/LibWeb/CSS/Parser/Token.h +++ b/Libraries/LibWeb/CSS/Parser/Token.h @@ -169,6 +169,11 @@ public: Position const& end_position() const { return m_end_position; } void set_position_range(Badge, Position start, Position end); + bool operator==(Token const& other) const + { + return m_type == other.m_type && m_value == other.m_value && m_number_value == other.m_number_value && m_hash_type == other.m_hash_type; + } + private: Type m_type { Type::Invalid }; diff --git a/Libraries/LibWeb/CSS/Parser/Types.h b/Libraries/LibWeb/CSS/Parser/Types.h index accb282a736..5d695fabe09 100644 --- a/Libraries/LibWeb/CSS/Parser/Types.h +++ b/Libraries/LibWeb/CSS/Parser/Types.h @@ -81,6 +81,8 @@ struct SimpleBlock { String to_string() const; String original_source_text() const; void contains_arbitrary_substitution_function(SubstitutionFunctionsPresence&) const; + + bool operator==(SimpleBlock const& other) const { return token == other.token && value == other.value; } }; // https://drafts.csswg.org/css-syntax/#function @@ -93,6 +95,8 @@ struct Function { String to_string() const; String original_source_text() const; void contains_arbitrary_substitution_function(SubstitutionFunctionsPresence&) const; + + bool operator==(Function const& other) const { return name == other.name && value == other.value; } }; // https://drafts.csswg.org/css-variables/#guaranteed-invalid-value @@ -100,6 +104,8 @@ struct GuaranteedInvalidValue { GuaranteedInvalidValue() = default; String to_string() const { return {}; } String original_source_text() const { return {}; } + + bool operator==(GuaranteedInvalidValue const&) const = default; }; } diff --git a/Libraries/LibWeb/CSS/StyleValues/UnresolvedStyleValue.cpp b/Libraries/LibWeb/CSS/StyleValues/UnresolvedStyleValue.cpp index a07f8664d62..d477b9ffca2 100644 --- a/Libraries/LibWeb/CSS/StyleValues/UnresolvedStyleValue.cpp +++ b/Libraries/LibWeb/CSS/StyleValues/UnresolvedStyleValue.cpp @@ -48,8 +48,7 @@ bool UnresolvedStyleValue::equals(CSSStyleValue const& other) const { if (type() != other.type()) return false; - // This is a case where comparing the strings actually makes sense. - return to_string(SerializationMode::Normal) == other.to_string(SerializationMode::Normal); + return values() == other.as_unresolved().values(); } }