LibWeb: Cache lowercased tag name for getElementsByTagName() iteration

Instead of calling to_lowercase() on two strings for every step while
iterating over the HTMLCollection returned by getElementsByTagName(),
we now cache the lowercased tag name beforehand and reuse it.

2.4x speed-up on WebKit/PerformanceTests/DOM/DOMDivWalk.html
This commit is contained in:
Andreas Kling 2023-08-22 14:34:25 +02:00
parent ec340f03a5
commit 76580bb9ba
Notes: sideshowbarker 2024-07-18 00:41:35 +09:00
5 changed files with 8 additions and 7 deletions

View File

@ -29,7 +29,7 @@ public:
DeprecatedFlyString const& namespace_uri() const { return m_qualified_name.namespace_(); }
DeprecatedFlyString const& prefix() const { return m_qualified_name.prefix(); }
DeprecatedFlyString const& local_name() const { return m_qualified_name.local_name(); }
DeprecatedString const& name() const { return m_qualified_name.as_string(); }
DeprecatedFlyString const& name() const { return m_qualified_name.as_string(); }
DeprecatedString const& value() const { return m_value; }
void set_value(DeprecatedString value);

View File

@ -705,7 +705,7 @@ void Element::make_html_uppercased_qualified_name()
{
// This is allowed by the spec: "User agents could optimize qualified name and HTML-uppercased qualified name by storing them in internal slots."
if (namespace_() == Namespace::HTML && document().document_type() == Document::Type::HTML)
m_html_uppercased_qualified_name = qualified_name().to_uppercase();
m_html_uppercased_qualified_name = DeprecatedString(qualified_name()).to_uppercase();
else
m_html_uppercased_qualified_name = qualified_name();
}

View File

@ -71,7 +71,7 @@ class Element
public:
virtual ~Element() override;
DeprecatedString const& qualified_name() const { return m_qualified_name.as_string(); }
DeprecatedFlyString const& qualified_name() const { return m_qualified_name.as_string(); }
DeprecatedString const& html_uppercased_qualified_name() const { return m_html_uppercased_qualified_name; }
virtual DeprecatedFlyString node_name() const final { return html_uppercased_qualified_name(); }
DeprecatedFlyString const& local_name() const { return m_qualified_name.local_name(); }

View File

@ -133,10 +133,11 @@ JS::NonnullGCPtr<HTMLCollection> ParentNode::get_elements_by_tag_name(Deprecated
// 2. Otherwise, if roots node document is an HTML document, return a HTMLCollection rooted at root, whose filter matches the following descendant elements:
if (root().document().document_type() == Document::Type::HTML) {
return HTMLCollection::create(*this, HTMLCollection::Scope::Descendants, [qualified_name](Element const& element) {
auto qualified_name_in_ascii_lowercase = qualified_name.to_lowercase();
return HTMLCollection::create(*this, HTMLCollection::Scope::Descendants, [qualified_name, qualified_name_in_ascii_lowercase](Element const& element) {
// - Whose namespace is the HTML namespace and whose qualified name is qualifiedName, in ASCII lowercase.
if (element.namespace_() == Namespace::HTML)
return element.qualified_name().to_lowercase() == qualified_name.to_lowercase();
return element.qualified_name() == qualified_name_in_ascii_lowercase;
// - Whose namespace is not the HTML namespace and whose qualified name is qualifiedName.
return element.qualified_name() == qualified_name;

View File

@ -19,7 +19,7 @@ public:
DeprecatedFlyString const& prefix() const { return m_impl->prefix; }
DeprecatedFlyString const& namespace_() const { return m_impl->namespace_; }
DeprecatedString const& as_string() const { return m_impl->as_string; }
DeprecatedFlyString const& as_string() const { return m_impl->as_string; }
struct Impl : public RefCounted<Impl> {
Impl(DeprecatedFlyString const& local_name, DeprecatedFlyString const& prefix, DeprecatedFlyString const& namespace_);
@ -29,7 +29,7 @@ public:
DeprecatedFlyString local_name;
DeprecatedFlyString prefix;
DeprecatedFlyString namespace_;
DeprecatedString as_string;
DeprecatedFlyString as_string;
};
void set_prefix(DeprecatedFlyString const& value);