///| Markdown parser benchmarks
///| Run with: moon bench --target js -p mizchi/luna/core/markdown
///|
/// Generate a sample markdown document of given size
fn generate_sample_markdown(paragraphs : Int) -> String {
let buf = StringBuilder::new()
// Frontmatter
buf.write_string("---\n")
buf.write_string("title: Benchmark Document\n")
buf.write_string("author: Test\n")
buf.write_string("---\n\n")
// Title
buf.write_string("# Benchmark Document\n\n")
// Content
for i = 0; i < paragraphs; i = i + 1 {
// Heading
buf.write_string("## Section \{i + 1}\n\n")
// Paragraph
buf.write_string(
"This is a paragraph of text. It contains some content that needs to be parsed. ",
)
buf.write_string("Markdown is a lightweight markup language. ")
buf.write_string("It is often used for formatting readme files.\n\n")
// Code block
buf.write_string("```javascript\n")
buf.write_string("function hello() {\n")
buf.write_string(" console.log('Hello, World!');\n")
buf.write_string("}\n")
buf.write_string("```\n\n")
// List
buf.write_string("- Item one\n")
buf.write_string("- Item two\n")
buf.write_string("- Item three\n\n")
// Blockquote
buf.write_string("> This is a blockquote.\n")
buf.write_string("> It spans multiple lines.\n\n")
}
buf.to_string()
}
// Pre-generate test documents
///|
let small_doc : String = generate_sample_markdown(5)
///|
let medium_doc : String = generate_sample_markdown(20)
///|
let large_doc : String = generate_sample_markdown(100)
///|
test "parse: small document (5 sections)" (b : @bench.T) {
b.bench(fn() {
let result = parse(small_doc)
b.keep(result)
})
}
///|
test "parse: medium document (20 sections)" (b : @bench.T) {
b.bench(fn() {
let result = parse(medium_doc)
b.keep(result)
})
}
///|
test "parse: large document (100 sections)" (b : @bench.T) {
b.bench(fn() {
let result = parse(large_doc)
b.keep(result)
})
}
///|
test "serialize: small document" (b : @bench.T) {
let parsed = parse(small_doc)
b.bench(fn() {
let output = serialize(parsed.document)
b.keep(output)
})
}
///|
test "serialize: medium document" (b : @bench.T) {
let parsed = parse(medium_doc)
b.bench(fn() {
let output = serialize(parsed.document)
b.keep(output)
})
}
///|
test "roundtrip: small document" (b : @bench.T) {
b.bench(fn() {
let result = parse(small_doc)
let output = serialize(result.document)
b.keep(output)
})
}
///|
test "roundtrip: medium document" (b : @bench.T) {
b.bench(fn() {
let result = parse(medium_doc)
let output = serialize(result.document)
b.keep(output)
})
}
// === Span allocation benchmark ===
///|
test "span: creation 1000x" (b : @bench.T) {
b.bench(fn() {
let mut last = Span::new(0, 0)
for i = 0; i < 1000; i = i + 1 {
last = Span::new(i, i + 10)
}
b.keep(last)
})
}