Performance
What's parallelized, why it's safe, and what makes serialization fast.
Design
- Hand-rolled single-pass lexer and recursive-descent parser; an
arena-based DOM (flat
Vec, index links) on top of quick-xml. - Rayon parallelism, applied at three levels:
- Documents referenced by distinct
USEsources load and parse in parallel. - Blocks targeting different documents execute in parallel; blocks targeting the same document stay sequential.
- Large
FOREACHloops (≥1024 children, noBREAK) evaluate their expressions in parallel before applying mutations sequentially — exact sequential semantics, parallel speed.TAGloops parallelize only when no match is nested inside another.
- Documents referenced by distinct
- Output strings are pre-sized from the DOM (both the serializer and the final output assembly), avoiding repeated reallocation on large documents.
Why parallel execution is safe here
The arena DOM (xml/dom.rs) stores nodes in a flat Vec<Element> linked
by plain usize indexes, rather than as a tree of owned/reference-counted
nodes. That layout is what makes read-only parallel evaluation over
&Document sound: many threads can read the same arena concurrently
without any interior mutability or locking, because evaluation never
mutates the arena directly — it only produces a plan.
The evaluate-then-apply split (in eval/mod.rs) is the other half:
for large loops, expression evaluation (which is read-only) runs in
parallel across children, producing a list of mutation plans; those plans
are then applied to the document sequentially, in original order. This
guarantees the observable result is bit-for-bit identical to running the
loop fully sequentially — parallelism only changes wall-clock time, never
behavior. Loops containing BREAK skip this entirely and run sequential,
since BREAK's early-exit semantics depend on visiting elements in a
fixed order.
Measuring it
SET FORMAT = OFF; compact output, if you don't need to eyeball the XML
ANALYZE; per-stage timing report on stderrANALYZE (or SET ANALYZE = ON) prints lex, parse, stdin/file read, XML
parse (per document), per-block execution, serialization, output assembly,
stdout write, total DOM memory, and total wall time — see
CLI: Diagnostics.