pygixml benchmark report · generated 2026-09-26 10:46 UTC

pygixml, measured honestly

Every independent way to work with XML this library offers — the core module, objectify, dictify, jsonify (both JSON and JSON Lines), and the command-line tool — each measured on its own against its real, direct competitor.

13 corpus entries · 7 repeats per cell
Package size

What you actually download

Real wheel sizes for the current platform and Python, resolved through pip-size's Python API — no downloads, no installs, just querying PyPI's index — summed across every transitive dependency, not just the top-level package. ElementTree ships with Python itself: 0 extra bytes.

PackageVersionInstalled sizeDepsCapability
ElementTree stdlib 0.0 KB 0 dom, streaming iterparse (Python standard library)
xmljson 0.2.1 9.9 KB 0 lxml/ElementTree tree → dict adapter
xmltodict 1.0.4 13.3 KB 0 dom → dict (+ streaming callback mode)
untangle 1.3.0 29.1 KB 1 dom → lazy attribute-style object (read-only)
pygixml ★ 0.12.2 402.5 KB 0 dom, streaming iterparse, objectify, dictify, jsonify, cli
yq 4.2.0 917.6 KB 4 cli: jq-style query/convert (installs the `xq` XML binary used below)
lxml 6.1.3 5120.0 KB 0 dom, streaming iterparse, objectify

Sizes measured with pip-size (lower is better). Deps count is transitive, flattened.

Core Module

Building and streaming a tree

The two fundamental ways to read XML: load the whole thing into memory at once, or walk it one element at a time without ever holding the whole document. Time per corpus entry (best of 7 runs) and peak memory (each measured in its own isolated process).

Parsing

parse — build a tree from the XML string, discard it

Directly building an in-memory tree from the XML text. xmltodict/xmljson have no separate “parse to a tree” step distinct from “parse straight to dict”, so they don't appear here.

pygixml is the reference (fastest most consistently across the corpus). On average (E[time/pygixml], mean of each entry's own ratio, not a ratio of medians): lxml 8.0×, ElementTree 12.7× as long.

ElementTree uses the least memory (uses the least memory most consistently across the corpus). On average (E[memory/ElementTree]): pygixml 1.1×, lxml 1.4× as much.

See per-entry detail (12 corpus entries)
rss/small
Time (ms, lower is better)
pygixml 0.039ms · lxml 0.217ms · ElementTree 0.363ms
Peak memory (MB, lower is better)
ElementTree 13.0MB · pygixml 15.8MB · lxml 18.9MB
rss/medium
Time (ms, lower is better)
pygixml 0.657ms · lxml 1.92ms · ElementTree 3.10ms
Peak memory (MB, lower is better)
ElementTree 14.7MB · pygixml 17.6MB · lxml 21.1MB
rss/large
Time (ms, lower is better)
pygixml 6.14ms · lxml 18.3ms · ElementTree 34.9ms
Peak memory (MB, lower is better)
ElementTree 33.4MB · pygixml 35.9MB · lxml 43.2MB
catalog/small
Time (ms, lower is better)
pygixml 0.051ms · lxml 0.479ms · ElementTree 0.701ms
Peak memory (MB, lower is better)
ElementTree 13.0MB · pygixml 15.9MB · lxml 19.1MB
catalog/medium
Time (ms, lower is better)
pygixml 0.366ms · lxml 4.03ms · ElementTree 6.66ms
Peak memory (MB, lower is better)
ElementTree 17.1MB · pygixml 18.6MB · lxml 23.6MB
catalog/large
Time (ms, lower is better)
pygixml 8.98ms · lxml 47.9ms · ElementTree 84.3ms
Peak memory (MB, lower is better)
pygixml 45.2MB · ElementTree 58.4MB · lxml 67.9MB
records/small
Time (ms, lower is better)
pygixml 0.031ms · lxml 0.353ms · ElementTree 0.399ms
Peak memory (MB, lower is better)
ElementTree 13.0MB · pygixml 15.7MB · lxml 18.8MB
records/medium
Time (ms, lower is better)
pygixml 0.224ms · lxml 2.50ms · ElementTree 3.79ms
Peak memory (MB, lower is better)
ElementTree 14.7MB · pygixml 17.5MB · lxml 21.5MB
records/large
Time (ms, lower is better)
pygixml 6.22ms · lxml 25.2ms · ElementTree 42.4ms
Peak memory (MB, lower is better)
ElementTree 33.5MB · pygixml 33.7MB · lxml 46.4MB
config/fixed
Time (ms, lower is better)
pygixml 0.219ms · lxml 1.61ms · ElementTree 4.10ms
Peak memory (MB, lower is better)
ElementTree 15.5MB · pygixml 16.9MB · lxml 20.4MB
real_svg_icons/small
Time (ms, lower is better)
pygixml 0.099ms · lxml 1.31ms · ElementTree 1.76ms
Peak memory (MB, lower is better)
ElementTree 13.6MB · pygixml 16.3MB · lxml 19.8MB
real_svg_icons/medium
Time (ms, lower is better)
pygixml 0.127ms · lxml 1.55ms · ElementTree 2.32ms
Peak memory (MB, lower is better)
ElementTree 13.9MB · pygixml 16.5MB · lxml 20.0MB

Time vs. input size (ms, log scale, lower is better)

Peak memory vs. input size (MB, lower is better)

Throughput vs. input size (MB/s, higher is better)

Streaming

iterparse — stream every element, never hold the whole document

Streamed via pygixml.iterfind, against lxml's and ElementTree's own iterparse -- real streaming APIs on both sides. Only runs on corpus entries with one uniformly repeated element (a config-tree genre genuinely has none, so it's absent here, not skipped by oversight).

lxml is the reference (fastest most consistently across the corpus). On average (E[time/lxml], mean of each entry's own ratio, not a ratio of medians): ElementTree 1.2×, pygixml 2.4× as long.

ElementTree uses the least memory (uses the least memory most consistently across the corpus). On average (E[memory/ElementTree]): pygixml 1.2×, lxml 1.5× as much.

See per-entry detail (9 corpus entries)
rss/small
Time (ms, lower is better)
lxml 0.447ms · ElementTree 0.587ms · pygixml 1.47ms
Peak memory (MB, lower is better)
ElementTree 13.0MB · pygixml 15.9MB · lxml 19.0MB
rss/medium
Time (ms, lower is better)
lxml 3.58ms · ElementTree 4.00ms · pygixml 13.3ms
Peak memory (MB, lower is better)
ElementTree 13.6MB · pygixml 16.7MB · lxml 19.9MB
rss/large
Time (ms, lower is better)
lxml 32.8ms · ElementTree 37.0ms · pygixml 133.9ms
Peak memory (MB, lower is better)
ElementTree 19.9MB · pygixml 22.5MB · lxml 28.8MB
catalog/small
Time (ms, lower is better)
lxml 0.794ms · ElementTree 0.894ms · pygixml 1.35ms
Peak memory (MB, lower is better)
ElementTree 13.0MB · pygixml 16.3MB · lxml 19.2MB
catalog/medium
Time (ms, lower is better)
lxml 7.33ms · ElementTree 8.71ms · pygixml 13.9ms
Peak memory (MB, lower is better)
ElementTree 13.8MB · pygixml 17.2MB · lxml 20.3MB
catalog/large
Time (ms, lower is better)
lxml 70.7ms · ElementTree 84.9ms · pygixml 135.0ms
Peak memory (MB, lower is better)
ElementTree 21.2MB · pygixml 24.1MB · lxml 30.3MB
records/small
Time (ms, lower is better)
lxml 0.465ms · ElementTree 0.670ms · pygixml 0.843ms
Peak memory (MB, lower is better)
ElementTree 13.1MB · pygixml 16.1MB · lxml 19.0MB
records/medium
Time (ms, lower is better)
lxml 4.78ms · ElementTree 5.48ms · pygixml 7.96ms
Peak memory (MB, lower is better)
ElementTree 13.4MB · pygixml 17.0MB · lxml 19.9MB
records/large
Time (ms, lower is better)
lxml 47.1ms · ElementTree 56.5ms · pygixml 85.4ms
Peak memory (MB, lower is better)
ElementTree 17.6MB · pygixml 20.5MB · lxml 26.8MB

Time vs. input size (ms, log scale, lower is better)

Peak memory vs. input size (MB, lower is better)

Throughput vs. input size (MB/s, higher is better)

Objectify

Lazy attribute-style access

Lazy attribute-style access (root.child.grandchild), matched against lxml's own objectify submodule -- a real feature both libraries ship, not an improvised comparison.

pygixml is the reference (fastest most consistently across the corpus). On average (E[time/pygixml], mean of each entry's own ratio, not a ratio of medians): lxml 7.8× as long.

pygixml uses the least memory (uses the least memory most consistently across the corpus). On average (E[memory/pygixml]): lxml 1.3× as much.

See per-entry detail (12 corpus entries)
rss/small
Time (ms, lower is better)
pygixml 0.037ms · lxml 0.226ms
Peak memory (MB, lower is better)
pygixml 15.9MB · lxml 19.8MB
rss/medium
Time (ms, lower is better)
pygixml 0.595ms · lxml 1.67ms
Peak memory (MB, lower is better)
pygixml 17.7MB · lxml 22.1MB
rss/large
Time (ms, lower is better)
pygixml 6.28ms · lxml 17.7ms
Peak memory (MB, lower is better)
pygixml 36.1MB · lxml 44.2MB
catalog/small
Time (ms, lower is better)
pygixml 0.050ms · lxml 0.470ms
Peak memory (MB, lower is better)
pygixml 15.9MB · lxml 20.1MB
catalog/medium
Time (ms, lower is better)
pygixml 0.366ms · lxml 3.98ms
Peak memory (MB, lower is better)
pygixml 18.6MB · lxml 24.6MB
catalog/large
Time (ms, lower is better)
pygixml 9.55ms · lxml 48.7ms
Peak memory (MB, lower is better)
pygixml 45.3MB · lxml 68.8MB
records/small
Time (ms, lower is better)
pygixml 0.035ms · lxml 0.305ms
Peak memory (MB, lower is better)
pygixml 15.9MB · lxml 19.9MB
records/medium
Time (ms, lower is better)
pygixml 0.229ms · lxml 2.57ms
Peak memory (MB, lower is better)
pygixml 17.5MB · lxml 22.3MB
records/large
Time (ms, lower is better)
pygixml 6.30ms · lxml 26.3ms
Peak memory (MB, lower is better)
pygixml 33.8MB · lxml 47.5MB
config/fixed
Time (ms, lower is better)
pygixml 0.227ms · lxml 1.56ms
Peak memory (MB, lower is better)
pygixml 16.9MB · lxml 21.4MB
real_svg_icons/small
Time (ms, lower is better)
pygixml 0.097ms · lxml 1.28ms
Peak memory (MB, lower is better)
pygixml 16.3MB · lxml 20.6MB
real_svg_icons/medium
Time (ms, lower is better)
pygixml 0.126ms · lxml 1.62ms
Peak memory (MB, lower is better)
pygixml 16.6MB · lxml 20.9MB

Time vs. input size (ms, log scale, lower is better)

Peak memory vs. input size (MB, lower is better)

Throughput vs. input size (MB/s, higher is better)

Dictify

XML to a plain dict

Two independent comparisons, not one: dictify's regular (DOM) mode against xmltodict.parse, and its streaming mode (dictify.iterdict) against xmltodict's own streaming mode (item_depth + item_callback) — xmltodict genuinely supports both, so neither comparison is a DOM tool facing off against a streaming-only one.

DOM mode

dictify.parse vs. xmltodict.parse

Both sides use the same convention (@-prefixed attributes, #text for mixed content) so the dicts they produce are structurally identical, not just “both happen to be a dict.”

pygixml is the reference (fastest most consistently across the corpus). On average (E[time/pygixml], mean of each entry's own ratio, not a ratio of medians): xmltodict 6.9× as long.

pygixml uses the least memory (uses the least memory most consistently across the corpus). On average (E[memory/pygixml]): xmltodict 1.2× as much.

See per-entry detail (12 corpus entries)
rss/small
Time (ms, lower is better)
pygixml 0.212ms · xmltodict 1.63ms
Peak memory (MB, lower is better)
pygixml 16.1MB · xmltodict 21.2MB
rss/medium
Time (ms, lower is better)
pygixml 2.19ms · xmltodict 15.0ms
Peak memory (MB, lower is better)
pygixml 18.8MB · xmltodict 22.9MB
rss/large
Time (ms, lower is better)
pygixml 24.4ms · xmltodict 154.8ms
Peak memory (MB, lower is better)
xmltodict 39.7MB · pygixml 46.4MB
catalog/small
Time (ms, lower is better)
pygixml 0.485ms · xmltodict 3.10ms
Peak memory (MB, lower is better)
pygixml 16.4MB · xmltodict 21.4MB
catalog/medium
Time (ms, lower is better)
pygixml 4.74ms · xmltodict 29.9ms
Peak memory (MB, lower is better)
pygixml 21.9MB · xmltodict 25.7MB
catalog/large
Time (ms, lower is better)
pygixml 80.1ms · xmltodict 358.5ms
Peak memory (MB, lower is better)
xmltodict 64.4MB · pygixml 78.5MB
records/small
Time (ms, lower is better)
pygixml 0.249ms · xmltodict 2.34ms
Peak memory (MB, lower is better)
pygixml 16.1MB · xmltodict 21.2MB
records/medium
Time (ms, lower is better)
pygixml 2.55ms · xmltodict 22.3ms
Peak memory (MB, lower is better)
pygixml 19.1MB · xmltodict 22.9MB
records/large
Time (ms, lower is better)
pygixml 38.5ms · xmltodict 220.2ms
Peak memory (MB, lower is better)
xmltodict 39.9MB · pygixml 50.1MB
config/fixed
Time (ms, lower is better)
pygixml 1.47ms · xmltodict 13.9ms
Peak memory (MB, lower is better)
pygixml 17.8MB · xmltodict 23.3MB
real_svg_icons/small
Time (ms, lower is better)
pygixml 0.714ms · xmltodict 3.84ms
Peak memory (MB, lower is better)
pygixml 17.1MB · xmltodict 22.1MB
real_svg_icons/medium
Time (ms, lower is better)
pygixml 0.810ms · xmltodict 4.69ms
Peak memory (MB, lower is better)
pygixml 17.3MB · xmltodict 22.4MB

Time vs. input size (ms, log scale, lower is better)

Peak memory vs. input size (MB, lower is better)

Throughput vs. input size (MB/s, higher is better)

Streaming mode

dictify.iterdict vs. xmltodict's item_depth/item_callback

xmltodict genuinely supports streaming too (item_depth + item_callback), not just a DOM-only tool being compared unfairly against a streaming one. Same record-tag restriction as iterparse.

pygixml is the reference (fastest most consistently across the corpus). On average (E[time/pygixml], mean of each entry's own ratio, not a ratio of medians): xmltodict 1.6× as long.

pygixml uses the least memory (uses the least memory most consistently across the corpus). On average (E[memory/pygixml]): xmltodict 1.3× as much.

See per-entry detail (9 corpus entries)
rss/small
Time (ms, lower is better)
xmltodict 1.61ms · pygixml 1.63ms
Peak memory (MB, lower is better)
pygixml 16.1MB · xmltodict 21.0MB
rss/medium
Time (ms, lower is better)
pygixml 14.6ms · xmltodict 14.7ms
Peak memory (MB, lower is better)
pygixml 16.9MB · xmltodict 21.8MB
rss/large
Time (ms, lower is better)
pygixml 147.1ms · xmltodict 158.5ms
Peak memory (MB, lower is better)
pygixml 22.5MB · xmltodict 29.2MB
catalog/small
Time (ms, lower is better)
pygixml 1.82ms · xmltodict 3.04ms
Peak memory (MB, lower is better)
pygixml 16.2MB · xmltodict 20.9MB
catalog/medium
Time (ms, lower is better)
pygixml 17.5ms · xmltodict 29.3ms
Peak memory (MB, lower is better)
pygixml 17.3MB · xmltodict 22.1MB
catalog/large
Time (ms, lower is better)
pygixml 181.9ms · xmltodict 295.0ms
Peak memory (MB, lower is better)
pygixml 24.0MB · xmltodict 31.0MB
records/small
Time (ms, lower is better)
pygixml 1.17ms · xmltodict 2.27ms
Peak memory (MB, lower is better)
pygixml 16.0MB · xmltodict 21.0MB
records/medium
Time (ms, lower is better)
pygixml 10.5ms · xmltodict 22.1ms
Peak memory (MB, lower is better)
pygixml 17.0MB · xmltodict 21.5MB
records/large
Time (ms, lower is better)
pygixml 102.2ms · xmltodict 208.1ms
Peak memory (MB, lower is better)
pygixml 20.5MB · xmltodict 25.8MB

Time vs. input size (ms, log scale, lower is better)

Peak memory vs. input size (MB, lower is better)

Throughput vs. input size (MB/s, higher is better)

DOM vs. streaming, both libraries, same axes (ms, log scale, lower is better)

Solid line = streaming mode, dashed = DOM mode — is streaming actually worth it, and for whom?

Jsonify

XML to JSON

Two independent output shapes, not one: a single JSON document for the whole input, or one JSON object per record, streamed out as JSON Lines.

JSON

jsonify.dumps — XML string in, one JSON document out

XML string in, one JSON document out. ElementTree has no built-in dict/JSON conversion at all -- a real gap for it, not an oversight in this chart.

On small documents, memory isn't the deciding factor for either approach -- both fit comfortably in RAM. What's left is speed, and there jsonify.dumps (the DOM path) wins clearly: on average 10.4× the speed of xmljson (E[timexmljson/timepygixml], mean of each small entry's own ratio). Even on memory -- where this is the DOM path, not stream_dump, so both sides are genuinely O(n) here, a fair same-complexity-class comparison -- pygixml still uses on average 1.2× less memory than xmljson on these same small files (E[memoryxmljson/memorypygixml]).

Once the document stops being small, the calculus changes: that's exactly when jsonify.stream_dump takes over, trading the DOM path's speed for a fundamentally different complexity class. pygixml (stream_dump) (O(1)) stayed within 15.7–15.7MB across every size tested, up to 62.7MB. See the memory panel below for the full trade-off, not just the flattering half.

pygixml is the reference (fastest most consistently across the corpus). On average (E[time/pygixml], mean of each entry's own ratio, not a ratio of medians): xmljson 10.3×, xmltodict 10.8× as long.

pygixml uses the least memory (uses the least memory most consistently across the corpus). On average (E[memory/pygixml]): xmltodict 1.3×, xmljson 1.3× as much.

See per-entry detail (12 corpus entries)
rss/small
Time (ms, lower is better)
pygixml 0.171ms · xmltodict 1.79ms · xmljson 2.23ms
Peak memory (MB, lower is better)
pygixml 15.9MB · xmljson 19.2MB · xmltodict 21.2MB
rss/medium
Time (ms, lower is better)
pygixml 1.86ms · xmltodict 14.9ms · xmljson 20.5ms
Peak memory (MB, lower is better)
pygixml 18.6MB · xmljson 22.7MB · xmltodict 22.9MB
rss/large
Time (ms, lower is better)
pygixml 20.4ms · xmltodict 167.3ms · xmljson 217.5ms
Peak memory (MB, lower is better)
xmltodict 42.6MB · pygixml 43.4MB · xmljson 58.7MB
catalog/small
Time (ms, lower is better)
pygixml 0.313ms · xmljson 2.69ms · xmltodict 3.66ms
Peak memory (MB, lower is better)
pygixml 16.0MB · xmljson 19.5MB · xmltodict 21.3MB
catalog/medium
Time (ms, lower is better)
pygixml 2.62ms · xmljson 22.7ms · xmltodict 30.2ms
Peak memory (MB, lower is better)
pygixml 19.6MB · xmltodict 25.8MB · xmljson 26.6MB
catalog/large
Time (ms, lower is better)
pygixml 39.1ms · xmljson 316.1ms · xmltodict 378.9ms
Peak memory (MB, lower is better)
pygixml 53.9MB · xmltodict 68.2MB · xmljson 87.7MB
records/small
Time (ms, lower is better)
pygixml 0.181ms · xmltodict 2.56ms · xmljson 2.64ms
Peak memory (MB, lower is better)
pygixml 15.9MB · xmljson 19.3MB · xmltodict 21.1MB
records/medium
Time (ms, lower is better)
pygixml 1.55ms · xmltodict 22.5ms · xmljson 24.0ms
Peak memory (MB, lower is better)
pygixml 17.9MB · xmltodict 23.0MB · xmljson 24.5MB
records/large
Time (ms, lower is better)
pygixml 22.2ms · xmltodict 243.2ms · xmljson 294.0ms
Peak memory (MB, lower is better)
pygixml 37.8MB · xmltodict 39.8MB · xmljson 69.2MB
config/fixed
Time (ms, lower is better)
pygixml 1.09ms · xmljson 11.3ms · xmltodict 15.1ms
Peak memory (MB, lower is better)
pygixml 17.1MB · xmljson 21.6MB · xmltodict 23.2MB
real_svg_icons/small
Time (ms, lower is better)
pygixml 0.524ms · xmljson 2.72ms · xmltodict 4.63ms
Peak memory (MB, lower is better)
pygixml 16.8MB · xmljson 20.1MB · xmltodict 22.1MB
real_svg_icons/medium
Time (ms, lower is better)
pygixml 0.727ms · xmljson 3.24ms · xmltodict 5.57ms
Peak memory (MB, lower is better)
pygixml 17.3MB · xmljson 20.3MB · xmltodict 22.3MB

Time vs. input size (ms, log scale, lower is better)

Peak memory vs. input size (MB, lower is better)

Throughput vs. input size (MB/s, higher is better)

Peak RSS vs. input size (MB, log scale, lower is better)

The streaming variant of this same JSON output, jsonify.stream_dump, never holds the whole document in memory: its curve stays flat — O(1) against every DOM-based approach's O(n). That's a difference in growth rate, not a fixed multiplier: no single "N× less memory" number at one input size represents it fairly — the chart does. Largest file in this comparison: 62.7MB.

pygixml (stream_dump) (O(1)) stayed within 15.7–15.7MB across every size tested, up to 62.7MB. Among the O(n), DOM-based approaches only (a fair comparison -- same complexity class): pygixml (DOM) is the reference (uses the least memory most consistently across the sizes tested); on average (E[memory/pygixml (DOM)], mean of each size's own ratio): xmltodict 1.0×, lxml + xmljson 2.1× as much.

stream_dump speed vs. input size (log scale, lower is better)

Best of 3 timed repeats per process, after one untimed warm-up call.

stream_dump time vs. N, by input shape (log-log, lower is better)

stream_dump writes optimistically and patches the output file in place once it learns a tag repeats — O(n) for the shape almost all real giant XML actually has (one repeated tag per nesting level). We also generate the one shape where it isn't: two different tags repeating and interleaving at the same level, shown here on purpose, not just cited in the docs.

N grew 256× (500 → 128,000): records-shape time grew 261.6× (linear, tracks N); interleaved-shape time grew 1343.8× (superlinear, approaching the documented O(n²) case). The slope, not a single ratio, is the finding.

Records-shape XML → JSON, DOM-based approaches, for reference

Everyone's roughly-linear time on the realistic shape, at moderate N.

JSON Lines

jsonify.iterjsonl — one JSON object per record, streamed

The streaming sibling of the panel above: instead of one JSON value for the whole document, one JSON object per matching element, read one at a time. xmltodict's own item_depth/item_callback streaming mode is the fair reference here too -- json.dumps happens per callback, same as pygixml emits per element. Same uniformly-repeated-tag restriction as streaming/iterparse above.

xmltodict is the reference (fastest most consistently across the corpus). On average (E[time/xmltodict], mean of each entry's own ratio, not a ratio of medians): pygixml 1.2× as long.

See per-entry detail (9 corpus entries)
rss/small
Time (ms, lower is better)
xmltodict 2.01ms · pygixml 3.54ms
rss/medium
Time (ms, lower is better)
xmltodict 17.2ms · pygixml 30.8ms
rss/large
Time (ms, lower is better)
xmltodict 185.9ms · pygixml 318.7ms
catalog/small
Time (ms, lower is better)
xmltodict 3.79ms · pygixml 4.02ms
catalog/medium
Time (ms, lower is better)
pygixml 35.2ms · xmltodict 36.9ms
catalog/large
Time (ms, lower is better)
xmltodict 360.9ms · pygixml 388.2ms
records/small
Time (ms, lower is better)
pygixml 2.03ms · xmltodict 2.62ms
records/medium
Time (ms, lower is better)
pygixml 20.2ms · xmltodict 25.9ms
records/large
Time (ms, lower is better)
pygixml 202.8ms · xmltodict 254.9ms

Time vs. input size (ms, log scale, lower is better)

Throughput vs. input size (MB/s, higher is better)

Command line

pygixml vs. xq, at the shell

python -m pygixml jsonify against xq . (installed by pip install yq) — real subprocess invocations end to end, process startup included on both sides, best of 5 runs.

On average (E[timexq/timepygixml], mean of each corpus entry's own ratio): pygixml's CLI takes 3.5× xq's time, i.e. xq takes 0.3× as long, across 12 corpus entries.

See per-entry detail (12 corpus entries)
rss/small
Time (ms, lower is better)
pygixml 38.7ms · xq 91.4ms
rss/medium
Time (ms, lower is better)
pygixml 38.4ms · xq 117.5ms
rss/large
Time (ms, lower is better)
pygixml 64.7ms · xq 392.5ms
catalog/small
Time (ms, lower is better)
pygixml 35.7ms · xq 93.7ms
catalog/medium
Time (ms, lower is better)
pygixml 40.5ms · xq 159.9ms
catalog/large
Time (ms, lower is better)
pygixml 74.9ms · xq 881.2ms
records/small
Time (ms, lower is better)
pygixml 41.7ms · xq 108.5ms
records/medium
Time (ms, lower is better)
pygixml 43.0ms · xq 142.6ms
records/large
Time (ms, lower is better)
pygixml 58.3ms · xq 544.0ms
config/fixed
Time (ms, lower is better)
pygixml 36.4ms · xq 112.8ms
real_svg_icons/small
Time (ms, lower is better)
pygixml 39.2ms · xq 104.9ms
real_svg_icons/medium
Time (ms, lower is better)
pygixml 36.4ms · xq 105.0ms

Time vs. input size (ms, log scale, lower is better)

Environment

What this ran on

Every number above came from this one machine. Recorded automatically by system_info.py at run time — not filled in by hand.

CPUIntel(R) Xeon(R) Processor @ 2.10GHz
Logical cores1
RAM3.9 GiB
Architecturex86_64
OSLinux 6.18.44-fc-v42
PythonCPython 3.12.3