mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-01-23 17:52:26 -05:00
519a1cdc22
This completely changes how HTMLTokens store their data. Previously, space was allocated for all token types separately. Now, the HTMLToken's data is stored in just a String, two booleans and a Variant. This change reduces sizeof(HTMLToken) from 68 to 32. Also, this reduces raw tokenization time by around 20 to 50 percent, depending on the page. Full document parsing time (with HTMLDocumentParser, on a local HTML page without any dependency files) is reduced by between 4 and 20 percent, depending on the page. Since tokenizing HTML pages can easily generated 50'000 tokens and more, the storage has been designed in a way that avoids heap allocations where possible, while trying to reduce the size of the tokens. The only tokens which need to allocate on the heap are thus DOCTYPE tokens (max. 1 per document), and tag tokens (but only if they have attributes). This way, only around 5 percent of all tokens generated need to allocate on the heap (except for StringImpl allocations).
76 lines
2 KiB
C++
76 lines
2 KiB
C++
/*
|
|
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#include <LibWeb/HTML/Parser/HTMLToken.h>
|
|
|
|
namespace Web::HTML {
|
|
|
|
String HTMLToken::to_string() const
|
|
{
|
|
StringBuilder builder;
|
|
|
|
switch (type()) {
|
|
case HTMLToken::Type::DOCTYPE:
|
|
builder.append("DOCTYPE");
|
|
builder.append(" { name: '");
|
|
builder.append(doctype_data().name);
|
|
builder.append("' }");
|
|
break;
|
|
case HTMLToken::Type::StartTag:
|
|
builder.append("StartTag");
|
|
break;
|
|
case HTMLToken::Type::EndTag:
|
|
builder.append("EndTag");
|
|
break;
|
|
case HTMLToken::Type::Comment:
|
|
builder.append("Comment");
|
|
break;
|
|
case HTMLToken::Type::Character:
|
|
builder.append("Character");
|
|
break;
|
|
case HTMLToken::Type::EndOfFile:
|
|
builder.append("EndOfFile");
|
|
break;
|
|
case HTMLToken::Type::Invalid:
|
|
VERIFY_NOT_REACHED();
|
|
}
|
|
|
|
if (type() == HTMLToken::Type::StartTag || type() == HTMLToken::Type::EndTag) {
|
|
builder.append(" { name: '");
|
|
builder.append(tag_name());
|
|
builder.append("', { ");
|
|
for_each_attribute([&](auto& attribute) {
|
|
builder.append(attribute.local_name);
|
|
builder.append("=\"");
|
|
builder.append(attribute.value);
|
|
builder.append("\" ");
|
|
return IterationDecision::Continue;
|
|
});
|
|
builder.append("} }");
|
|
}
|
|
|
|
if (is_comment()) {
|
|
builder.append(" { data: '");
|
|
builder.append(comment());
|
|
builder.append("' }");
|
|
}
|
|
|
|
if (is_character()) {
|
|
builder.append(" { data: '");
|
|
builder.append_code_point(code_point());
|
|
builder.append("' }");
|
|
}
|
|
|
|
if (type() == HTMLToken::Type::Character) {
|
|
builder.appendff("@{}:{}", m_start_position.line, m_start_position.column);
|
|
} else {
|
|
builder.appendff("@{}:{}-{}:{}", m_start_position.line, m_start_position.column, m_end_position.line, m_end_position.column);
|
|
}
|
|
|
|
return builder.to_string();
|
|
}
|
|
|
|
}
|