Skip to content

Commit 81451bf

Browse files
LibWeb: Avoid O(n²) behavior in NamedNodeMap::supported_property_names
The function deduplicates attribute names in order. The previous implementation used Vector::contains_slow() inside the loop, making the overall complexity O(n²) in the number of attributes. Replace the in-place linear search with a HashTable<FlyString> that tracks which names have already been appended. Each set() call is O(1) amortized, reducing the total deduplication step from O(n²) to O(n). The pre-allocated hash table is initialised to the same capacity as the attribute list so reallocation is avoided in the common case where every attribute name is unique. Fixes #7980. Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
1 parent de10db6 commit 81451bf

File tree

1 file changed

+7
-1
lines changed

1 file changed

+7
-1
lines changed

Libraries/LibWeb/DOM/NamedNodeMap.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
* SPDX-License-Identifier: BSD-2-Clause
77
*/
88

9+
#include <AK/HashTable.h>
910
#include <LibWeb/Bindings/NamedNodeMapPrototype.h>
1011
#include <LibWeb/DOM/Attr.h>
1112
#include <LibWeb/DOM/Document.h>
@@ -55,9 +56,14 @@ Vector<FlyString> NamedNodeMap::supported_property_names() const
5556
Vector<FlyString> names;
5657
names.ensure_capacity(m_attributes.size());
5758

59+
// Use a hash set to track names seen so far, avoiding the O(n²) cost of
60+
// contains_slow() on the output vector for elements with many attributes.
61+
HashTable<FlyString> seen;
62+
seen.ensure_capacity(m_attributes.size());
63+
5864
for (auto const& attribute : m_attributes) {
5965
auto const attribute_name = attribute->name();
60-
if (!names.contains_slow(attribute_name))
66+
if (seen.set(attribute_name) == HashSetResult::InsertedNewEntry)
6167
names.append(attribute_name.to_string());
6268
}
6369

0 commit comments

Comments
 (0)