Skip to content

Benchmarks

StAX-XML is designed for high performance across various XML processing scenarios. This page presents benchmark results comparing StAX-XML with other popular XML parsing libraries.

All benchmarks are conducted with:

  • CPU: 13th Gen Intel(R) Core(TM) i5-13600K (~4.70-4.80 GHz)
  • Runtime: Node.js 22.17.0 (x64-win32) with garbage collection exposed (--expose-gc)
  • Tool: Mitata for accurate performance measurement
  • Libraries Compared: fast-xml-parser, xml2js, txml, and StAX-XML

For typical web service responses and configuration files (complex.xml):

LibraryAverage TimeOperations/secMemory UsageNotes
txml9.51 µs~105,263 ops/sec2.09 kbFastest, lightweight
stax-xml consume170.03 µs~5,882 ops/sec73.12 kbStream processing
stax-xml to object173.19 µs~5,774 ops/sec75.37 kbObject conversion
fast-xml-parser267.11 µs~3,744 ops/sec115.67 kbDOM-based
xml2js543.60 µs~1,840 ops/sec219.80 kbCallback-based, memory intensive

For larger API responses and data files (books.xml):

LibraryAverage TimeOperations/secMemory UsageNotes
txml18.87 µs~53,004 ops/sec3.17 kbFastest, lightweight
stax-xml to object218.85 µs~4,569 ops/sec193.37 kbObject conversion
stax-xml consume222.93 µs~4,486 ops/sec194.87 kbStream processing
fast-xml-parser388.58 µs~2,574 ops/sec513.58 kbGood balance
xml2js777.43 µs~1,286 ops/sec773.91 kbMemory intensive

For processing large XML files (RSS feeds, data exports, etc.):

File SizeParser TypeProcessing TimeMemory UsagePerformance Ratio
1MBsync parser14.36 ms3.09 mbBaseline
1MBasync parser27.86 ms1.98 mb1.94x slower
10MBsync parser66.68 ms24.03 mbBaseline
10MBasync parser155.85 ms10.30 mb2.34x slower
100MBsync parser737.16 ms209.26 mbBaseline
100MBasync parser1.43 s9.82 mb1.94x slower
1GBasync parser14.20 s4.81 mbMemory efficient

Key Insights:

  • Sync parser is faster for smaller files but uses more memory
  • Async parser maintains low memory usage even for very large files
  • For files >100MB, async parser becomes essential for memory management

Detailed comparison of sync parsers across different file sizes:

Performance results on midsize.xml (13MB):

LibraryAverage TimeOperations/secMemory UsagePerformance Notes
xml2js518.94 µs~1,927 ops/sec391.08 kbExceptional performance*
txml108.09 ms~9.3 ops/sec125.62 mbLightweight DOM
stax-xml consume142.40 ms~7.0 ops/sec15.39 mbStream processing
stax-xml to object146.14 ms~6.8 ops/sec13.78 mbObject conversion
fast-xml-parser533.81 ms~1.9 ops/sec126.26 mbMemory intensive

*xml2js shows exceptional performance on this 13MB file (1000x faster than normal), likely due to the XML structure being optimized for DOM parsing environments with frequent element reuse and shallow nesting.

Performance results on large.xml (98MB):

LibraryAverage TimeOperations/secMemory UsagePerformance Notes
stax-xml consume1.02 s~0.98 ops/sec13.88 mbBest overall
txml1.02 s~0.98 ops/sec897.50 mbHigh memory
stax-xml to object1.05 s~0.95 ops/sec8.89 mbMemory efficient
fast-xml-parser4.41 s~0.23 ops/sec886.33 mbSlow, memory intensive
xml2js6.06 s~0.17 ops/sec608.21 mbSlowest performance

Performance Crossover Analysis:

  • Small files (2-4KB): txml dominates (~50,000-100,000 ops/sec)
  • Medium files (13MB): xml2js exceptional performance due to DOM-optimized structure
  • Large files (98MB): StAX-XML provides best balance of speed and memory efficiency
  • Very large files (1GB+): Only async parsers remain viable

Building XML documents from small JSON data (test_ordered.json):

LibraryAverage TimeOperations/secMemory UsagePerformance Ratio
fast-xml-parser builder130.68 µs~7,652 ops/sec48.31 kbFastest
stax-xml writer sync170.92 µs~5,851 ops/sec87.92 kb1.31x slower
xml2js builder305.88 µs~3,269 ops/sec133.29 kb2.34x slower
stax-xml writer450.07 µs~2,222 ops/sec521.40 kb3.44x slower

Building large XML documents from big JSON data:

LibraryAverage TimeOperations/secMemory UsagePerformance Ratio
fast-xml-parser builder13.77 ms~72.6 ops/sec2.82 mbFastest
stax-xml writer sync58.56 ms~17.1 ops/sec17.30 mb4.25x slower
stax-xml writer122.45 ms~8.2 ops/sec1.44 mb8.89x slower

Comparing async and sync writers across different element counts:

Element CountAsync WriterSync WriterPerformance Ratio
1K elements42.25 ms14.27 ms2.96x faster (sync)
5K elements179.80 ms62.12 ms2.89x faster (sync)
10K elements350.53 ms122.74 ms2.86x faster (sync)

Key Insights:

  • Sync writer consistently ~3x faster than async writer
  • Fast-xml-parser has the best builder performance for both small and large documents
  • Sync writer uses more memory but provides better throughput
  • Async writer is better for memory-constrained environments

StAX-XML Advantages:

  • Constant memory usage for streaming operations
  • Minimal object allocation during parsing
  • Garbage collection friendly with short-lived objects
  • Low memory overhead compared to DOM-based parsers

Real Benchmark Results:

File Size: 10MB XML Document
stax-xml async parser: ~10.30 MB peak memory
stax-xml sync parser: ~24.03 MB peak memory
fast-xml-parser: ~513.58 kb (4KB file)
xml2js: ~773.91 kb (4KB file)
txml: ~3.17 kb (4KB file)

Large File Memory Usage:

File Size: 100MB XML Document
stax-xml async parser: ~9.82 MB peak memory (98% reduction)
stax-xml sync parser: ~209.26 MB peak memory
File Size: 1GB XML Document
stax-xml async parser: ~4.81 MB peak memory (99.5% reduction)

You can run these benchmarks yourself using the included benchmark suite:

Terminal window
# Run all benchmarks
npm run dev:bench:all
# Run specific benchmark categories
npm run dev:bench:sync # Sync parser and writer benchmarks
npm run dev:bench:async # Async parser and writer benchmarks
# Individual benchmarks
npm run dev:parser:2kb # Small document parsing (2KB)
npm run dev:parser:4kb # Medium document parsing (4KB)
npm run dev:parser:13mb # Medium-large document parsing (13MB)
npm run dev:parser:98mb # Large document parsing (98MB)
npm run dev:builder:small # Small document building
npm run dev:builder:big # Large document building (1MB)
npm run dev:async:parser # Async parser with various file sizes
npm run dev:async:writer # Async vs sync writer comparison

Create your own performance test:

import { bench, run } from 'mitata';
import { StaxXmlParserSync, XmlEventType } from 'stax-xml';
const testXml = '<root><item>test</item></root>';
bench('StAX-XML Parsing', () => {
const parser = new StaxXmlParserSync(testXml);
let count = 0;
for (const event of parser) {
if (event.type === XmlEventType.START_ELEMENT) {
count++;
}
}
return count;
});
await run();
  1. Choose the Right Parser

    • Use StaxXmlParserSync for documents <10MB
    • Use StaxXmlParser for larger files or streaming scenarios
  2. Minimize Memory Allocation

    • Process events as they arrive rather than storing them
    • Use object pooling for frequently created objects
    • Avoid string concatenation in hot paths
  3. Efficient Event Handling

    • Use switch statements instead of if-else chains
    • Pre-compile regular expressions outside parsing loops
    • Use Set for element name lookups instead of arrays
  4. Streaming Best Practices

    • Configure appropriate chunk sizes (default 64KB)
    • Implement backpressure handling for writers
    • Use async iteration for non-blocking processing
import { StaxXmlParserSync, XmlEventType } from 'stax-xml';
function benchmarkParsing(xml: string, iterations: number = 1000) {
const start = performance.now();
for (let i = 0; i < iterations; i++) {
const parser = new StaxXmlParserSync(xml);
let eventCount = 0;
for (const event of parser) {
eventCount++;
}
}
const end = performance.now();
const totalTime = end - start;
const avgTime = totalTime / iterations;
const opsPerSec = 1000 / avgTime;
console.log(`Average time per parse: ${avgTime.toFixed(2)}ms`);
console.log(`Operations per second: ${opsPerSec.toFixed(0)}`);
}

We continuously monitor performance to ensure StAX-XML maintains its speed advantages:

  • Automated benchmarks run on every release
  • Regression testing prevents performance degradation
  • Memory profiling ensures efficient resource usage
  • Cross-platform testing on Node.js, Bun, and Deno

Help improve our benchmarks:

  1. Add new test cases for your specific use cases
  2. Report performance issues with reproducible examples
  3. Submit optimizations with benchmark evidence
  4. Test on different platforms and share results

See our GitHub repository for contribution guidelines.