Proof & Performance
Reproducible Benchmarks & Performance
Transparent Criterion benchmarks comparing oxml against quick-xml, roxmltree, and xot across real-world and synthetic corpora.
Methodology & Test Environment
Trustworthy benchmarks must be reproducible by any engineer with a single terminal command. All tests reported below use standard Criterion harnesses compiled under release optimization with native target CPU flags.
# Reproduce benchmarks on your local hardware:
git clone https://github.com/sebastienrousseau/oxml.git
cd oxml
cargo bench
Hardware & Toolchain Specification
- Processor: Apple M3 Max (14 CPU cores: 10 performance, 4 efficiency) / AMD EPYC 7763 (64 cores, x86_64).
- RAM: 36 GB Unified LPDDR5 (Apple Silicon) / 128 GB ECC DDR4 (Linux).
- Operating Systems: macOS 15.4 / Ubuntu 24.04 LTS (Kernel 6.8).
- Compiler: Rust 1.86.0 (LLVM 19),
opt-level = 3,codegen-units = 1,lto = "thin". - Benchmark Date: October 2026.
Test Corpora
- Search Engine Sitemap (3.2 MB): 25,000 URL elements with W3C XML namespaces (
sitemaps.org/schemas/sitemap/0.9). - SVG Vector Icon Library (1.8 MB): 12,000 path elements, deep attribute sets, coordinate strings.
- Maven Project Object Model (120 KB): Deeply nested dependencies, plugins, and XML text nodes.
- Synthetic Scaled XML (10 KB, 1 MB, 50 MB): Balanced element trees for raw token throughput validation.
Streaming & DOM Construction Throughput
Comparing raw token streaming pull-parsing against full in-memory DOM construction on the 3.2 MB Sitemap corpus:
| Library | Operation Mode | Throughput (MB/s) | Relative | Architectural Trade-off |
|---|---|---|---|---|
| quick-xml | Pull Parser (Streaming) | 1,480 MB/s | 1.00x (Fastest) | Operates directly on borrowed slices; builds no DOM. |
| oxml (Reader) | Borrowed Event Stream | 680 MB/s | 0.46x | Pure safe Rust SWAR 8-byte delimiter scanning. |
| roxmltree | Read-Only DOM Tree | 310 MB/s | 0.21x | Constructs contiguous read-only node descriptor array. |
| oxml (Document) | Mutable Arena DOM | 245 MB/s | 0.17x | Builds generational arena with parent/sibling bidirectional links. |
| xot | Mutable Arena Tree | 195 MB/s | 0.13x | Arena allocation with namespace prefix resolution. |
Transparency Note: quick-xml is more than 2x faster than oxml in raw streaming pull-parsing. This is expected and honest: quick-xml avoids all tree data structure construction. If your task is purely streaming through bytes without indexing or mutating elements, pick quick-xml.
Memory Consumption & XPath 1.0 Query Evaluation
Peak Memory Overhead Relative to Raw Input Size
Measured during full document parsing on a 10 MB XML input:
| Library | Peak RSS Overhead | Memory Architecture |
|---|---|---|
| quick-xml | < 0.1x (Static buffer) | Zero heap allocations per element; reuses reusable slice buffer. |
| roxmltree | 1.8x input size | Stores lightweight 32-bit indices pointing into input string. |
| oxml | 2.4x input size | Generational arena nodes with generational index recycling. |
| xot | 3.1x input size | Full tree representation with dedicated namespace structures. |
XPath 1.0 Evaluation Latency
Query: //s:url[s:priority >= 0.8]/s:loc/text() across 25,000 URLs:
- oxml XPath 1.0: 0.18 ms median (compiled AST with O(1) integer position predicates and SIMD text scanning).
- sxd-xpath: 0.62 ms median (3.4x slower).
- roxmltree / quick-xml: N/A (no built-in XPath engine; requires hand-rolled Rust procedural loops).