Section ") buf.write_string(s.to_string()) buf.write_string("
") for p = 0; p < 3; p = p + 1 { buf.write_string("Paragraph ") buf.write_string(p.to_string()) buf.write_string( " with bold and italic text.
", ) } buf.write_string("// =============================================================================
// HTML Parser Benchmarks
// =============================================================================
// Benchmarks for measuring HTML parsing performance
// =============================================================================
// Test Data Generators
// =============================================================================
///|
/// Generate simple HTML with N elements
fn generate_simple_html(n : Int) -> String {
let buf = StringBuilder::new()
buf.write_string("")
for i = 0; i < n; i = i + 1 {
buf.write_string("Item ")
buf.write_string(i.to_string())
buf.write_string("
")
}
buf.write_string("")
buf.to_string()
}
///|
/// Generate nested HTML with depth D
fn generate_nested_html(depth : Int) -> String {
let buf = StringBuilder::new()
for i = 0; i < depth; i = i + 1 {
buf.write_string("")
}
buf.write_string("Content")
for _i = 0; _i < depth; _i = _i + 1 {
buf.write_string("")
}
buf.to_string()
}
///|
/// Generate HTML with many attributes
fn generate_attribute_heavy_html(n : Int) -> String {
let buf = StringBuilder::new()
buf.write_string("")
for i = 0; i < n; i = i + 1 {
buf.write_string("")
buf.write_string("Text ")
buf.write_string(i.to_string())
buf.write_string("")
}
buf.write_string("")
buf.to_string()
}
///|
/// Generate a table with R rows and C columns
fn generate_table_html(rows : Int, cols : Int) -> String {
let buf = StringBuilder::new()
buf.write_string("")
buf.write_string("")
for c = 0; c < cols; c = c + 1 {
buf.write_string("Header ")
buf.write_string(c.to_string())
buf.write_string(" ")
}
buf.write_string(" ")
buf.write_string("")
for r = 0; r < rows; r = r + 1 {
buf.write_string("")
for c = 0; c < cols; c = c + 1 {
buf.write_string("Cell ")
buf.write_string(r.to_string())
buf.write_string("-")
buf.write_string(c.to_string())
buf.write_string(" ")
}
buf.write_string(" ")
}
buf.write_string("")
buf.write_string("
")
buf.to_string()
}
///|
/// Generate a complex page layout (header, nav, main, footer)
fn generate_page_layout(sidebar_items : Int, content_sections : Int) -> String {
let buf = StringBuilder::new()
buf.write_string(
"Page ",
)
// Header
buf.write_string(" ")
// Main with sidebar
buf.write_string("")
for s = 0; s < content_sections; s = s + 1 {
buf.write_string("Section ")
buf.write_string(s.to_string())
buf.write_string("
")
for p = 0; p < 3; p = p + 1 {
buf.write_string("Paragraph ")
buf.write_string(p.to_string())
buf.write_string(
" with bold and italic text.
",
)
}
buf.write_string(" ")
}
buf.write_string(" ")
// Footer
buf.write_string("")
buf.write_string("")
buf.to_string()
}
///|
/// Generate HTML with inline styles (CSS in style attribute)
fn generate_styled_html(n : Int) -> String {
let buf = StringBuilder::new()
buf.write_string("")
for i = 0; i < n; i = i + 1 {
buf.write_string(
"",
)
buf.write_string("Label ")
buf.write_string(i.to_string())
buf.write_string("")
buf.write_string(
"Value",
)
buf.write_string("")
}
buf.write_string("")
buf.to_string()
}
///|
/// Generate HTML with script and style tags (to test extraction)
fn generate_resource_heavy_html(styles : Int, scripts : Int) -> String {
let buf = StringBuilder::new()
buf.write_string("")
for i = 0; i < styles; i = i + 1 {
buf.write_string("",
)
}
buf.write_string("")
buf.write_string("Content")
for i = 0; i < scripts; i = i + 1 {
buf.write_string("")
}
buf.write_string("")
buf.to_string()
}
///|
/// Generate form HTML with various input types
fn generate_form_html(fields : Int) -> String {
let buf = StringBuilder::new()
buf.write_string("")
buf.to_string()
}
///|
/// Generate HTML with malformed/edge case content (for error recovery testing)
fn generate_malformed_html(n : Int) -> String {
let buf = StringBuilder::new()
buf.write_string("")
for i = 0; i < n; i = i + 1 {
// Mix of well-formed and malformed
match i % 4 {
0 => {
// Missing closing tag
buf.write_string("Unclosed paragraph ")
buf.write_string(i.to_string())
}
1 => {
// Self-closing in wrong place
buf.write_string("
Text ")
buf.write_string(i.to_string())
}
2 => {
// Nested improperly
buf.write_string("Bold italic ")
buf.write_string(i.to_string())
buf.write_string("")
}
_ => {
// Well-formed
buf.write_string("Normal ")
buf.write_string(i.to_string())
buf.write_string("")
}
}
}
buf.write_string("")
buf.to_string()
}
// =============================================================================
// Parse Benchmarks
// =============================================================================
///|
test "bench_parse_simple_10" (b : @bench.T) {
let html = generate_simple_html(10)
b.bench(name="parse_simple_10", fn() { b.keep(parse(html)) })
}
///|
test "bench_parse_simple_100" (b : @bench.T) {
let html = generate_simple_html(100)
b.bench(name="parse_simple_100", fn() { b.keep(parse(html)) })
}
///|
test "bench_parse_simple_500" (b : @bench.T) {
let html = generate_simple_html(500)
b.bench(name="parse_simple_500", fn() { b.keep(parse(html)) })
}
///|
test "bench_parse_simple_1000" (b : @bench.T) {
let html = generate_simple_html(1000)
b.bench(name="parse_simple_1000", fn() { b.keep(parse(html)) })
}
// =============================================================================
// Nested Structure Benchmarks
// =============================================================================
///|
test "bench_parse_nested_10" (b : @bench.T) {
let html = generate_nested_html(10)
b.bench(name="parse_nested_10", fn() { b.keep(parse(html)) })
}
///|
test "bench_parse_nested_50" (b : @bench.T) {
let html = generate_nested_html(50)
b.bench(name="parse_nested_50", fn() { b.keep(parse(html)) })
}
///|
test "bench_parse_nested_100" (b : @bench.T) {
let html = generate_nested_html(100)
b.bench(name="parse_nested_100", fn() { b.keep(parse(html)) })
}
// =============================================================================
// Attribute-Heavy Benchmarks
// =============================================================================
///|
test "bench_parse_attrs_50" (b : @bench.T) {
let html = generate_attribute_heavy_html(50)
b.bench(name="parse_attrs_50", fn() { b.keep(parse(html)) })
}
///|
test "bench_parse_attrs_200" (b : @bench.T) {
let html = generate_attribute_heavy_html(200)
b.bench(name="parse_attrs_200", fn() { b.keep(parse(html)) })
}
///|
test "bench_parse_attrs_500" (b : @bench.T) {
let html = generate_attribute_heavy_html(500)
b.bench(name="parse_attrs_500", fn() { b.keep(parse(html)) })
}
// =============================================================================
// Table Benchmarks
// =============================================================================
///|
test "bench_parse_table_10x5" (b : @bench.T) {
let html = generate_table_html(10, 5)
b.bench(name="parse_table_10x5", fn() { b.keep(parse(html)) })
}
///|
test "bench_parse_table_50x10" (b : @bench.T) {
let html = generate_table_html(50, 10)
b.bench(name="parse_table_50x10", fn() { b.keep(parse(html)) })
}
///|
test "bench_parse_table_100x20" (b : @bench.T) {
let html = generate_table_html(100, 20)
b.bench(name="parse_table_100x20", fn() { b.keep(parse(html)) })
}
// =============================================================================
// Page Layout Benchmarks
// =============================================================================
///|
test "bench_parse_page_small" (b : @bench.T) {
let html = generate_page_layout(5, 3)
b.bench(name="parse_page_small", fn() { b.keep(parse_document(html)) })
}
///|
test "bench_parse_page_medium" (b : @bench.T) {
let html = generate_page_layout(15, 10)
b.bench(name="parse_page_medium", fn() { b.keep(parse_document(html)) })
}
///|
test "bench_parse_page_large" (b : @bench.T) {
let html = generate_page_layout(30, 20)
b.bench(name="parse_page_large", fn() { b.keep(parse_document(html)) })
}
// =============================================================================
// Styled HTML Benchmarks (CSS in style attributes)
// =============================================================================
///|
test "bench_parse_styled_50" (b : @bench.T) {
let html = generate_styled_html(50)
b.bench(name="parse_styled_50", fn() { b.keep(parse(html)) })
}
///|
test "bench_parse_styled_200" (b : @bench.T) {
let html = generate_styled_html(200)
b.bench(name="parse_styled_200", fn() { b.keep(parse(html)) })
}
// =============================================================================
// Resource Extraction Benchmarks
// =============================================================================
///|
test "bench_parse_resources_10" (b : @bench.T) {
let html = generate_resource_heavy_html(10, 10)
b.bench(name="parse_resources_10", fn() { b.keep(parse_document(html)) })
}
///|
test "bench_parse_resources_50" (b : @bench.T) {
let html = generate_resource_heavy_html(50, 50)
b.bench(name="parse_resources_50", fn() { b.keep(parse_document(html)) })
}
// =============================================================================
// Form Benchmarks
// =============================================================================
///|
test "bench_parse_form_10" (b : @bench.T) {
let html = generate_form_html(10)
b.bench(name="parse_form_10", fn() { b.keep(parse(html)) })
}
///|
test "bench_parse_form_50" (b : @bench.T) {
let html = generate_form_html(50)
b.bench(name="parse_form_50", fn() { b.keep(parse(html)) })
}
// =============================================================================
// Error Recovery Benchmarks
// =============================================================================
///|
test "bench_parse_malformed_50" (b : @bench.T) {
let html = generate_malformed_html(50)
b.bench(name="parse_malformed_50", fn() { b.keep(parse(html)) })
}
///|
test "bench_parse_malformed_200" (b : @bench.T) {
let html = generate_malformed_html(200)
b.bench(name="parse_malformed_200", fn() { b.keep(parse(html)) })
}
// =============================================================================
// Fragment Parse Benchmarks
// =============================================================================
///|
test "bench_parse_fragment_simple" (b : @bench.T) {
let html = "Simple paragraph with bold text
"
b.bench(name="parse_frag_simple", fn() { b.keep(parse_fragment(html)) })
}
///|
test "bench_parse_fragment_list" (b : @bench.T) {
let buf = StringBuilder::new()
buf.write_string("")
for i = 0; i < 20; i = i + 1 {
buf.write_string("- Item ")
buf.write_string(i.to_string())
buf.write_string("
")
}
buf.write_string("
")
let html = buf.to_string()
b.bench(name="parse_frag_list", fn() { b.keep(parse_fragment(html)) })
}
// =============================================================================
// Real-World HTML Snippets
// =============================================================================
///|
fn generate_card_grid(cards : Int) -> String {
let buf = StringBuilder::new()
buf.write_string(
"",
)
for i = 0; i < cards; i = i + 1 {
buf.write_string(
"",
)
buf.write_string("
",
)
buf.write_string("Card Title ")
buf.write_string(i.to_string())
buf.write_string("
")
buf.write_string(
"Card description goes here.
",
)
buf.write_string(
"",
)
buf.write_string("")
}
buf.write_string("")
buf.to_string()
}
///|
test "bench_parse_card_grid_12" (b : @bench.T) {
let html = generate_card_grid(12)
b.bench(name="parse_card_12", fn() { b.keep(parse(html)) })
}
///|
test "bench_parse_card_grid_48" (b : @bench.T) {
let html = generate_card_grid(48)
b.bench(name="parse_card_48", fn() { b.keep(parse(html)) })
}
///|
test "bench_parse_card_grid_100" (b : @bench.T) {
let html = generate_card_grid(100)
b.bench(name="parse_card_100", fn() { b.keep(parse(html)) })
}
// =============================================================================
// Tokenizer Only Benchmarks (measure tokenization speed)
// =============================================================================
///|
test "bench_tokenize_simple_100" (b : @bench.T) {
let html = generate_simple_html(100)
b.bench(name="tokenize_100", fn() {
let tokenizer = Tokenizer::new(html)
while true {
match tokenizer.next_token() {
EOF => break
_ => ()
}
}
b.keep(tokenizer)
})
}
///|
test "bench_tokenize_attrs_100" (b : @bench.T) {
let html = generate_attribute_heavy_html(100)
b.bench(name="tokenize_attrs_100", fn() {
let tokenizer = Tokenizer::new(html)
while true {
match tokenizer.next_token() {
EOF => break
_ => ()
}
}
b.keep(tokenizer)
})
}
///|
test "bench_tokenize_styled_100" (b : @bench.T) {
let html = generate_styled_html(100)
b.bench(name="tokenize_styled_100", fn() {
let tokenizer = Tokenizer::new(html)
while true {
match tokenizer.next_token() {
EOF => break
_ => ()
}
}
b.keep(tokenizer)
})
}
// =============================================================================
// Large Document Benchmarks
// =============================================================================
///|
fn generate_large_document(
sections : Int,
paragraphs_per_section : Int,
) -> String {
let buf = StringBuilder::new()
buf.write_string("Large Document ")
buf.write_string("")
buf.write_string("")
buf.write_string("Large Document
")
buf.write_string("")
for s = 0; s < sections; s = s + 1 {
buf.write_string("")
buf.write_string("Section ")
buf.write_string(s.to_string())
buf.write_string("
")
for p = 0; p < paragraphs_per_section; p = p + 1 {
buf.write_string(
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
",
)
}
buf.write_string(" ")
}
buf.write_string(" ")
buf.write_string("")
buf.write_string("")
buf.to_string()
}
///|
test "bench_parse_large_doc_10x5" (b : @bench.T) {
let html = generate_large_document(10, 5)
b.bench(name="parse_large_10x5", fn() { b.keep(parse_document(html)) })
}
///|
test "bench_parse_large_doc_50x10" (b : @bench.T) {
let html = generate_large_document(50, 10)
b.bench(name="parse_large_50x10", fn() { b.keep(parse_document(html)) })
}
///|
test "bench_parse_large_doc_100x20" (b : @bench.T) {
let html = generate_large_document(100, 20)
b.bench(name="parse_large_100x20", fn() { b.keep(parse_document(html)) })
}
// =============================================================================
// TreeBuilder Direct Benchmarks
// =============================================================================
///|
test "bench_treebuilder_simple_100" (b : @bench.T) {
let html = generate_simple_html(100)
b.bench(name="treebuilder_100", fn() {
let tokenizer = Tokenizer::new(html)
let builder = TreeBuilder::new(tokenizer)
b.keep(builder.build())
})
}
///|
test "bench_treebuilder_nested_50" (b : @bench.T) {
let html = generate_nested_html(50)
b.bench(name="treebuilder_nested_50", fn() {
let tokenizer = Tokenizer::new(html)
let builder = TreeBuilder::new(tokenizer)
b.keep(builder.build())
})
}
///|
test "bench_treebuilder_malformed_100" (b : @bench.T) {
let html = generate_malformed_html(100)
b.bench(name="treebuilder_malformed", fn() {
let tokenizer = Tokenizer::new(html)
let builder = TreeBuilder::new(tokenizer)
b.keep(builder.build())
})
}