json2xml 6.0.7__tar.gz → 6.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. {json2xml-6.0.7 → json2xml-6.2.0}/CONTRIBUTING.rst +12 -1
  2. {json2xml-6.0.7 → json2xml-6.2.0}/HISTORY.rst +18 -0
  3. {json2xml-6.0.7 → json2xml-6.2.0}/PKG-INFO +136 -5
  4. {json2xml-6.0.7 → json2xml-6.2.0}/README.rst +132 -2
  5. json2xml-6.2.0/docs/benchmarks.rst +203 -0
  6. json2xml-6.2.0/docs/rust_memory_benchmark.rst +110 -0
  7. {json2xml-6.0.7 → json2xml-6.2.0}/docs/usage.rst +46 -0
  8. {json2xml-6.0.7 → json2xml-6.2.0}/json2xml/__init__.py +1 -1
  9. {json2xml-6.0.7 → json2xml-6.2.0}/json2xml/cli.py +25 -5
  10. {json2xml-6.0.7 → json2xml-6.2.0}/json2xml/dicttoxml.py +150 -40
  11. {json2xml-6.0.7 → json2xml-6.2.0}/json2xml/dicttoxml_fast.py +10 -9
  12. {json2xml-6.0.7 → json2xml-6.2.0}/json2xml/json2xml.py +6 -4
  13. {json2xml-6.0.7 → json2xml-6.2.0}/json2xml/utils.py +19 -5
  14. {json2xml-6.0.7 → json2xml-6.2.0}/json2xml.egg-info/PKG-INFO +136 -5
  15. {json2xml-6.0.7 → json2xml-6.2.0}/json2xml.egg-info/SOURCES.txt +3 -0
  16. {json2xml-6.0.7 → json2xml-6.2.0}/json2xml.egg-info/requires.txt +3 -2
  17. {json2xml-6.0.7 → json2xml-6.2.0}/pyproject.toml +4 -3
  18. {json2xml-6.0.7 → json2xml-6.2.0}/requirements.in +1 -1
  19. {json2xml-6.0.7 → json2xml-6.2.0}/setup.cfg +1 -1
  20. {json2xml-6.0.7 → json2xml-6.2.0}/tests/test_cli.py +35 -5
  21. {json2xml-6.0.7 → json2xml-6.2.0}/tests/test_dict2xml.py +78 -0
  22. json2xml-6.2.0/tests/test_dicttoxml_fast_fallback.py +137 -0
  23. json2xml-6.2.0/tests/test_dicttoxml_unit.py +163 -0
  24. {json2xml-6.0.7 → json2xml-6.2.0}/tests/test_json2xml.py +27 -0
  25. {json2xml-6.0.7 → json2xml-6.2.0}/tests/test_rust_dicttoxml.py +4 -4
  26. {json2xml-6.0.7 → json2xml-6.2.0}/tests/test_utils.py +2 -2
  27. json2xml-6.0.7/docs/benchmarks.rst +0 -221
  28. {json2xml-6.0.7 → json2xml-6.2.0}/AUTHORS.rst +0 -0
  29. {json2xml-6.0.7 → json2xml-6.2.0}/LICENSE +0 -0
  30. {json2xml-6.0.7 → json2xml-6.2.0}/MANIFEST.in +0 -0
  31. {json2xml-6.0.7 → json2xml-6.2.0}/docs/Makefile +0 -0
  32. {json2xml-6.0.7 → json2xml-6.2.0}/docs/authors.rst +0 -0
  33. {json2xml-6.0.7 → json2xml-6.2.0}/docs/conf.py +0 -0
  34. {json2xml-6.0.7 → json2xml-6.2.0}/docs/contributing.rst +0 -0
  35. {json2xml-6.0.7 → json2xml-6.2.0}/docs/history.rst +0 -0
  36. {json2xml-6.0.7 → json2xml-6.2.0}/docs/index.rst +0 -0
  37. {json2xml-6.0.7 → json2xml-6.2.0}/docs/installation.rst +0 -0
  38. {json2xml-6.0.7 → json2xml-6.2.0}/docs/json2xml.rst +0 -0
  39. {json2xml-6.0.7 → json2xml-6.2.0}/docs/make.bat +0 -0
  40. {json2xml-6.0.7 → json2xml-6.2.0}/docs/modules.rst +0 -0
  41. {json2xml-6.0.7 → json2xml-6.2.0}/docs/readme.rst +0 -0
  42. {json2xml-6.0.7 → json2xml-6.2.0}/json2xml/types.py +0 -0
  43. {json2xml-6.0.7 → json2xml-6.2.0}/json2xml.egg-info/dependency_links.txt +0 -0
  44. {json2xml-6.0.7 → json2xml-6.2.0}/json2xml.egg-info/entry_points.txt +0 -0
  45. {json2xml-6.0.7 → json2xml-6.2.0}/json2xml.egg-info/top_level.txt +0 -0
  46. {json2xml-6.0.7 → json2xml-6.2.0}/setup.py +0 -0
  47. {json2xml-6.0.7 → json2xml-6.2.0}/tests/__init__.py +0 -0
  48. {json2xml-6.0.7 → json2xml-6.2.0}/tests/conftest.py +0 -0
  49. {json2xml-6.0.7 → json2xml-6.2.0}/tests/test_missing_coverage.py +0 -0
@@ -9,6 +9,17 @@ helps, and credit will always be given.
9
9
 
10
10
  You can contribute in many ways:
11
11
 
12
+ Good First Contributions
13
+ ------------------------
14
+
15
+ If you are new to the project, these are useful places to start:
16
+
17
+ * Improve examples for real-world API responses, files, and command-line usage.
18
+ * Add small tests around conversion options such as wrappers, list handling, CDATA, and XPath output.
19
+ * Improve benchmark documentation or add a reproducible benchmark case.
20
+ * Polish CLI behavior, error messages, and help text.
21
+ * Review the roadmap in ``ROADMAP.md`` and open a focused issue before starting larger changes.
22
+
12
23
  Types of Contributions
13
24
  ----------------------
14
25
 
@@ -99,7 +110,7 @@ Ready to contribute? Here's how to set up `json2xml` for local development.
99
110
  Rust Extension Development
100
111
  --------------------------
101
112
 
102
- The ``json2xml-rs`` Rust extension provides ~29x faster performance. If you want to contribute to the Rust extension:
113
+ The ``json2xml-rs`` Rust extension provides ~57-129x faster performance in the current benchmark. If you want to contribute to the Rust extension:
103
114
 
104
115
  **Prerequisites**
105
116
 
@@ -1,4 +1,22 @@
1
1
 
2
+ 6.2.0 / 2026-06-05
3
+ ==================
4
+
5
+ * feat: reduce peak serializer memory in the pure Python rooted-output path
6
+ * feat: reduce Rust extension peak serializer memory by writing directly into Python bytes
7
+ * fix: split PyO3 extension-module linking so ``cargo test`` works on macOS
8
+ * chore: release ``json2xml-rs`` 0.3.0 and make ``json2xml[fast]`` require the memory-saving Rust package
9
+ * chore: update the Rust extension crate to Rust 2024 with rust-version 1.96
10
+ * docs: add reproducible Rust memory benchmark results showing about 49% lower serializer RSS delta
11
+
12
+
13
+ 6.1.0 / 2026-05-04
14
+ ==================
15
+
16
+ * fix: address open contribution issues (#292)
17
+ * docs: improve README and add public roadmap (#287)
18
+
19
+
2
20
  6.0.7 / 2026-04-26
3
21
  ==================
4
22
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: json2xml
3
- Version: 6.0.7
3
+ Version: 6.2.0
4
4
  Summary: Simple Python Library to convert JSON to XML
5
5
  Author-email: Vinit Kumar <mail@vinitkumar.me>
6
6
  License: Apache Software License 2.0
@@ -23,15 +23,16 @@ Description-Content-Type: text/x-rst
23
23
  License-File: LICENSE
24
24
  License-File: AUTHORS.rst
25
25
  Requires-Dist: defusedxml
26
- Requires-Dist: urllib3
26
+ Requires-Dist: urllib3>=2.7.0
27
27
  Provides-Extra: dev
28
28
  Requires-Dist: pytest>=8.4.1; extra == "dev"
29
29
  Requires-Dist: pytest-cov; extra == "dev"
30
30
  Requires-Dist: coverage; extra == "dev"
31
31
  Requires-Dist: setuptools; extra == "dev"
32
+ Requires-Dist: pygments>=2.20.0; extra == "dev"
32
33
  Requires-Dist: xmltodict>=0.12.0; extra == "dev"
33
34
  Provides-Extra: fast
34
- Requires-Dist: json2xml-rs>=0.1.0; extra == "fast"
35
+ Requires-Dist: json2xml-rs>=0.3.0; extra == "fast"
35
36
  Dynamic: license-file
36
37
 
37
38
  .. image:: ./json2xml-hero.png
@@ -54,7 +55,7 @@ json2xml
54
55
  .. image:: https://codecov.io/gh/vinitkumar/json2xml/branch/master/graph/badge.svg?token=Yt2h55eTL2
55
56
  :target: https://codecov.io/gh/vinitkumar/json2xml
56
57
 
57
- json2xml is a Python library that allows you to convert JSON data into XML format. It's simple, efficient, and easy to use.
58
+ json2xml is a Python library and CLI for converting JSON data into XML. It is designed for teams that need predictable XML output, Python-first ergonomics, and a faster native path when conversion speed matters.
58
59
 
59
60
  Documentation: https://json2xml.readthedocs.io.
60
61
 
@@ -62,6 +63,137 @@ The library was initially dependent on the `dict2xml` project, but it has now be
62
63
 
63
64
  **Looking for a Go version?** Check out `json2xml-go <https://github.com/vinitkumar/json2xml-go>`_, a Go port of this library with identical features and a native CLI tool.
64
65
 
66
+ Why json2xml?
67
+ ^^^^^^^^^^^^^
68
+
69
+ Use json2xml when you need:
70
+
71
+ * A Python library for turning dictionaries, strings, files, or API responses into XML
72
+ * A command-line tool for quick JSON-to-XML conversion from scripts and terminals
73
+ * Optional Rust acceleration with automatic fallback to the pure Python implementation
74
+ * XPath 3.1 compatible output when standards-friendly XML is required
75
+ * A small, focused project with tests, docs, benchmarks, and multiple native implementation experiments
76
+
77
+ Quick Start
78
+ ^^^^^^^^^^^
79
+
80
+ Install the Python package:
81
+
82
+ .. code-block:: console
83
+
84
+ pip install json2xml
85
+
86
+ Use it from Python:
87
+
88
+ .. code-block:: python
89
+
90
+ from json2xml import json2xml
91
+ from json2xml.utils import readfromstring
92
+
93
+ data = readfromstring('{"name": "Ada", "language": "Python"}')
94
+ print(json2xml.Json2xml(data).to_xml())
95
+
96
+ Use it from the terminal:
97
+
98
+ .. code-block:: console
99
+
100
+ json2xml-py -s '{"name": "Ada", "language": "Python"}'
101
+
102
+ Install the accelerated path:
103
+
104
+ .. code-block:: console
105
+
106
+ pip install json2xml[fast]
107
+
108
+ Real-world Examples
109
+ ^^^^^^^^^^^^^^^^^^^
110
+
111
+ Convert a JSON API response in Python when another system expects XML:
112
+
113
+ .. code-block:: python
114
+
115
+ from json2xml import json2xml
116
+
117
+ api_response = {"user": {"id": 7, "name": "Ada"}, "active": True}
118
+ print(json2xml.Json2xml(api_response, pretty=False).to_xml().decode("utf-8"))
119
+
120
+ Output:
121
+
122
+ .. code-block:: xml
123
+
124
+ <?xml version="1.0" encoding="UTF-8" ?><all><user type="dict"><id type="int">7</id><name type="str">Ada</name></user><active type="bool">true</active></all>
125
+
126
+ Convert a local JSON export from the shell:
127
+
128
+ .. code-block:: console
129
+
130
+ cat > orders.json <<'JSON'
131
+ {"orders":[{"id":"A100","total":19.99},{"id":"A101","total":5.5}]}
132
+ JSON
133
+ json2xml-py --no-pretty --no-type orders.json
134
+
135
+ Output:
136
+
137
+ .. code-block:: xml
138
+
139
+ <?xml version="1.0" encoding="UTF-8" ?><all><orders><item><id>A100</id><total>19.99</total></item><item><id>A101</id><total>5.5</total></item></orders></all>
140
+
141
+ Convert stdin in a shell pipeline:
142
+
143
+ .. code-block:: console
144
+
145
+ printf '%s\n' '{"event":"deploy","status":"ok"}' | json2xml-py --no-pretty --no-type -
146
+
147
+ Output:
148
+
149
+ .. code-block:: xml
150
+
151
+ <?xml version="1.0" encoding="UTF-8" ?><all><event>deploy</event><status>ok</status></all>
152
+
153
+ Performance Snapshot
154
+ ^^^^^^^^^^^^^^^^^^^^
155
+
156
+ The optional Rust extension is the fastest path for Python callers because it avoids process startup overhead and falls back to pure Python when a feature is not supported natively.
157
+
158
+ .. list-table::
159
+ :header-rows: 1
160
+ :widths: 30 20 20 15
161
+
162
+ * - Test Case
163
+ - Pure Python
164
+ - Rust Extension
165
+ - Speedup
166
+ * - **Small JSON** (47 bytes)
167
+ - 31.49µs
168
+ - 0.55µs
169
+ - **56.8x**
170
+ * - **Medium JSON** (3.2 KB)
171
+ - 1.69ms
172
+ - 16.15µs
173
+ - **105.0x**
174
+ * - **Large JSON** (32 KB)
175
+ - 17.97ms
176
+ - 168.21µs
177
+ - **106.8x**
178
+ * - **Very Large JSON** (323 KB)
179
+ - 183.33ms
180
+ - 1.42ms
181
+ - **129.0x**
182
+
183
+ See `BENCHMARKS.md <https://github.com/vinitkumar/json2xml/blob/master/BENCHMARKS.md>`_ for the full Python, Rust, Go, and Zig comparison.
184
+
185
+ Project Roadmap
186
+ ^^^^^^^^^^^^^^^
187
+
188
+ The next phase of json2xml is focused on making the project easier to adopt, benchmark, and contribute to:
189
+
190
+ * Improve examples for common API, file, and CLI workflows
191
+ * Add clearer contribution paths for docs, CLI polish, and benchmark coverage
192
+ * Keep comparing Python, Rust, Go, and Zig implementations with reproducible benchmarks
193
+ * Continue hardening the Rust extension fallback behavior across platforms
194
+
195
+ See `ROADMAP.md <https://github.com/vinitkumar/json2xml/blob/master/ROADMAP.md>`_ for more detail.
196
+
65
197
 
66
198
 
67
199
  Architecture Diagram
@@ -574,4 +706,3 @@ Help and Support to maintain this project
574
706
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
575
707
 
576
708
  - You can sponsor my work for this plugin here: https://github.com/sponsors/vinitkumar/
577
-
@@ -18,7 +18,7 @@ json2xml
18
18
  .. image:: https://codecov.io/gh/vinitkumar/json2xml/branch/master/graph/badge.svg?token=Yt2h55eTL2
19
19
  :target: https://codecov.io/gh/vinitkumar/json2xml
20
20
 
21
- json2xml is a Python library that allows you to convert JSON data into XML format. It's simple, efficient, and easy to use.
21
+ json2xml is a Python library and CLI for converting JSON data into XML. It is designed for teams that need predictable XML output, Python-first ergonomics, and a faster native path when conversion speed matters.
22
22
 
23
23
  Documentation: https://json2xml.readthedocs.io.
24
24
 
@@ -26,6 +26,137 @@ The library was initially dependent on the `dict2xml` project, but it has now be
26
26
 
27
27
  **Looking for a Go version?** Check out `json2xml-go <https://github.com/vinitkumar/json2xml-go>`_, a Go port of this library with identical features and a native CLI tool.
28
28
 
29
+ Why json2xml?
30
+ ^^^^^^^^^^^^^
31
+
32
+ Use json2xml when you need:
33
+
34
+ * A Python library for turning dictionaries, strings, files, or API responses into XML
35
+ * A command-line tool for quick JSON-to-XML conversion from scripts and terminals
36
+ * Optional Rust acceleration with automatic fallback to the pure Python implementation
37
+ * XPath 3.1 compatible output when standards-friendly XML is required
38
+ * A small, focused project with tests, docs, benchmarks, and multiple native implementation experiments
39
+
40
+ Quick Start
41
+ ^^^^^^^^^^^
42
+
43
+ Install the Python package:
44
+
45
+ .. code-block:: console
46
+
47
+ pip install json2xml
48
+
49
+ Use it from Python:
50
+
51
+ .. code-block:: python
52
+
53
+ from json2xml import json2xml
54
+ from json2xml.utils import readfromstring
55
+
56
+ data = readfromstring('{"name": "Ada", "language": "Python"}')
57
+ print(json2xml.Json2xml(data).to_xml())
58
+
59
+ Use it from the terminal:
60
+
61
+ .. code-block:: console
62
+
63
+ json2xml-py -s '{"name": "Ada", "language": "Python"}'
64
+
65
+ Install the accelerated path:
66
+
67
+ .. code-block:: console
68
+
69
+ pip install json2xml[fast]
70
+
71
+ Real-world Examples
72
+ ^^^^^^^^^^^^^^^^^^^
73
+
74
+ Convert a JSON API response in Python when another system expects XML:
75
+
76
+ .. code-block:: python
77
+
78
+ from json2xml import json2xml
79
+
80
+ api_response = {"user": {"id": 7, "name": "Ada"}, "active": True}
81
+ print(json2xml.Json2xml(api_response, pretty=False).to_xml().decode("utf-8"))
82
+
83
+ Output:
84
+
85
+ .. code-block:: xml
86
+
87
+ <?xml version="1.0" encoding="UTF-8" ?><all><user type="dict"><id type="int">7</id><name type="str">Ada</name></user><active type="bool">true</active></all>
88
+
89
+ Convert a local JSON export from the shell:
90
+
91
+ .. code-block:: console
92
+
93
+ cat > orders.json <<'JSON'
94
+ {"orders":[{"id":"A100","total":19.99},{"id":"A101","total":5.5}]}
95
+ JSON
96
+ json2xml-py --no-pretty --no-type orders.json
97
+
98
+ Output:
99
+
100
+ .. code-block:: xml
101
+
102
+ <?xml version="1.0" encoding="UTF-8" ?><all><orders><item><id>A100</id><total>19.99</total></item><item><id>A101</id><total>5.5</total></item></orders></all>
103
+
104
+ Convert stdin in a shell pipeline:
105
+
106
+ .. code-block:: console
107
+
108
+ printf '%s\n' '{"event":"deploy","status":"ok"}' | json2xml-py --no-pretty --no-type -
109
+
110
+ Output:
111
+
112
+ .. code-block:: xml
113
+
114
+ <?xml version="1.0" encoding="UTF-8" ?><all><event>deploy</event><status>ok</status></all>
115
+
116
+ Performance Snapshot
117
+ ^^^^^^^^^^^^^^^^^^^^
118
+
119
+ The optional Rust extension is the fastest path for Python callers because it avoids process startup overhead and falls back to pure Python when a feature is not supported natively.
120
+
121
+ .. list-table::
122
+ :header-rows: 1
123
+ :widths: 30 20 20 15
124
+
125
+ * - Test Case
126
+ - Pure Python
127
+ - Rust Extension
128
+ - Speedup
129
+ * - **Small JSON** (47 bytes)
130
+ - 31.49µs
131
+ - 0.55µs
132
+ - **56.8x**
133
+ * - **Medium JSON** (3.2 KB)
134
+ - 1.69ms
135
+ - 16.15µs
136
+ - **105.0x**
137
+ * - **Large JSON** (32 KB)
138
+ - 17.97ms
139
+ - 168.21µs
140
+ - **106.8x**
141
+ * - **Very Large JSON** (323 KB)
142
+ - 183.33ms
143
+ - 1.42ms
144
+ - **129.0x**
145
+
146
+ See `BENCHMARKS.md <https://github.com/vinitkumar/json2xml/blob/master/BENCHMARKS.md>`_ for the full Python, Rust, Go, and Zig comparison.
147
+
148
+ Project Roadmap
149
+ ^^^^^^^^^^^^^^^
150
+
151
+ The next phase of json2xml is focused on making the project easier to adopt, benchmark, and contribute to:
152
+
153
+ * Improve examples for common API, file, and CLI workflows
154
+ * Add clearer contribution paths for docs, CLI polish, and benchmark coverage
155
+ * Keep comparing Python, Rust, Go, and Zig implementations with reproducible benchmarks
156
+ * Continue hardening the Rust extension fallback behavior across platforms
157
+
158
+ See `ROADMAP.md <https://github.com/vinitkumar/json2xml/blob/master/ROADMAP.md>`_ for more detail.
159
+
29
160
 
30
161
 
31
162
  Architecture Diagram
@@ -538,4 +669,3 @@ Help and Support to maintain this project
538
669
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
539
670
 
540
671
  - You can sponsor my work for this plugin here: https://github.com/sponsors/vinitkumar/
541
-
@@ -0,0 +1,203 @@
1
+ Benchmarks
2
+ ==========
3
+
4
+ Comprehensive performance comparison between all json2xml implementations.
5
+
6
+ Test Environment
7
+ ----------------
8
+
9
+ * **Machine**: Apple Silicon (arm64)
10
+ * **OS**: macOS 26.5 (Darwin 25.5.0)
11
+ * **Python**: 3.14.4
12
+ * **Date**: May 27, 2026
13
+ * **CLI tools**: ``json2xml-go`` and ``json2xml-zig`` from ``/Users/vinitkumar/.local/bin``
14
+
15
+ Implementations Tested
16
+ ~~~~~~~~~~~~~~~~~~~~~~
17
+
18
+ .. list-table::
19
+ :header-rows: 1
20
+ :widths: 25 20 55
21
+
22
+ * - Implementation
23
+ - Type
24
+ - Notes
25
+ * - Python
26
+ - Library
27
+ - Pure Python ``json2xml``
28
+ * - Rust
29
+ - Library
30
+ - Native extension via PyO3, imported as ``json2xml_rs``
31
+ * - Go
32
+ - CLI
33
+ - Standalone ``json2xml-go`` binary
34
+ * - Zig
35
+ - CLI
36
+ - Standalone ``json2xml-zig`` binary
37
+
38
+ Test Data
39
+ ~~~~~~~~~
40
+
41
+ .. list-table::
42
+ :header-rows: 1
43
+ :widths: 20 55 25
44
+
45
+ * - Size
46
+ - Description
47
+ - Bytes
48
+ * - Small
49
+ - Simple object ``{"name": "John", "age": 30, "city": "New York"}``
50
+ - 47
51
+ * - Medium
52
+ - 10 generated records with nested structures
53
+ - 3,215
54
+ * - bigexample.json
55
+ - Real-world patent data
56
+ - 2,018
57
+ * - Large
58
+ - 100 generated records with nested structures
59
+ - 32,206
60
+ * - Very Large
61
+ - 1,000 generated records with nested structures
62
+ - 323,131
63
+
64
+ Results
65
+ -------
66
+
67
+ Performance Summary
68
+ ~~~~~~~~~~~~~~~~~~~
69
+
70
+ .. list-table::
71
+ :header-rows: 1
72
+ :widths: 28 18 18 18 18
73
+
74
+ * - Test Case
75
+ - Python
76
+ - Rust
77
+ - Go
78
+ - Zig
79
+ * - Small (47B)
80
+ - 3.19µs
81
+ - 0.86µs
82
+ - 6.05ms
83
+ - 3.08ms
84
+ * - Medium (3.2KB)
85
+ - 214.83µs
86
+ - 18.41µs
87
+ - 5.85ms
88
+ - 3.12ms
89
+ * - bigexample (2KB)
90
+ - 91.20µs
91
+ - 7.32µs
92
+ - 5.76ms
93
+ - 3.08ms
94
+ * - Large (32KB)
95
+ - 2.07ms
96
+ - 175.46µs
97
+ - 5.89ms
98
+ - 3.73ms
99
+ * - Very Large (323KB)
100
+ - 21.20ms
101
+ - 1.48ms
102
+ - 6.82ms
103
+ - 7.82ms
104
+
105
+ Speedup vs Pure Python
106
+ ~~~~~~~~~~~~~~~~~~~~~~
107
+
108
+ .. list-table::
109
+ :header-rows: 1
110
+ :widths: 34 22 22 22
111
+
112
+ * - Test Case
113
+ - Rust
114
+ - Go
115
+ - Zig
116
+ * - Small (47B)
117
+ - **3.7x**
118
+ - 0.0x*
119
+ - 0.0x*
120
+ * - Medium (3.2KB)
121
+ - **11.7x**
122
+ - 0.0x*
123
+ - 0.1x*
124
+ * - bigexample (2KB)
125
+ - **12.5x**
126
+ - 0.0x*
127
+ - 0.0x*
128
+ * - Large (32KB)
129
+ - **11.8x**
130
+ - 0.4x*
131
+ - 0.6x*
132
+ * - Very Large (323KB)
133
+ - **14.4x**
134
+ - **3.1x**
135
+ - **2.7x**
136
+
137
+ *CLI tools have process spawn overhead of about 3-6ms, which dominates for small inputs.*
138
+
139
+ Key Observations
140
+ ----------------
141
+
142
+ Rust remains the best option for Python library calls. It avoids process overhead and is about 4-14x faster than the optimized pure Python path in this run.
143
+
144
+ Recent pure Python improvements substantially reduced conversion time. Medium and large inputs are roughly an order of magnitude faster than the April 2026 baseline, so relative Rust speedups are lower even though Rust is still fastest.
145
+
146
+ Go and Zig remain useful for native CLI workflows. They are slower for small and medium inputs because startup dominates, but both beat Python on the 323KB workload when full CLI process time is measured.
147
+
148
+ See ``docs/rust_memory_benchmark.rst`` for the June 2026 Rust peak-memory comparison between the previous extension-boundary copy and the Python bytes-writer implementation.
149
+
150
+ When to Use Each Implementation
151
+ -------------------------------
152
+
153
+ .. list-table::
154
+ :header-rows: 1
155
+ :widths: 40 25 35
156
+
157
+ * - Use Case
158
+ - Recommended
159
+ - Why
160
+ * - Python library calls
161
+ - **Rust**
162
+ - 4-14x faster, no process overhead
163
+ * - Small files via CLI
164
+ - **Zig**
165
+ - Fastest startup among native CLIs in this run
166
+ * - Large files via CLI
167
+ - **Go** or **Zig**
168
+ - Both are faster than Python at 323KB
169
+ * - Batch processing
170
+ - **Go** or **Rust**
171
+ - Choose based on shell vs Python integration
172
+ * - Pure Python required
173
+ - **Python**
174
+ - Always available
175
+
176
+ Running the Benchmarks
177
+ ----------------------
178
+
179
+ Run benchmarks from a clean checkout with the project installed in an isolated environment.
180
+
181
+ .. code-block:: bash
182
+
183
+ uv venv
184
+ source .venv/bin/activate
185
+ uv pip install -e .
186
+ python benchmark_all.py
187
+
188
+ For Rust benchmarks, install the extension into the same environment.
189
+
190
+ .. code-block:: bash
191
+
192
+ uv pip install maturin
193
+ cd rust
194
+ maturin develop --release
195
+ cd ..
196
+
197
+ For native CLI benchmarks, install the external tools and verify that the commands are visible.
198
+
199
+ .. code-block:: bash
200
+
201
+ go install github.com/vinitkumar/json2xml-go@latest
202
+ which json2xml-go
203
+ which json2xml-zig
@@ -0,0 +1,110 @@
1
+ Rust Memory Benchmark
2
+ =====================
3
+
4
+ This benchmark compares peak memory usage before and after the Rust serializer started writing directly into Python ``bytes``.
5
+
6
+ Summary
7
+ -------
8
+
9
+ The current branch reduces serializer peak RSS by about **77.44 MiB** on a 100,000-record payload that produces **78.17 MiB** of XML. That is a **49.1% reduction** in serializer memory delta compared with the previous PR commit.
10
+
11
+ .. list-table::
12
+ :header-rows: 1
13
+ :widths: 24 22 22 22 22
14
+
15
+ * - Version
16
+ - Commit
17
+ - Avg peak RSS
18
+ - Avg serializer delta
19
+ - Avg time
20
+ * - Previous
21
+ - ``7dd86b0``
22
+ - 349.15 MiB
23
+ - 157.70 MiB
24
+ - 0.180s
25
+ * - Current
26
+ - ``07d840f``
27
+ - 271.65 MiB
28
+ - 80.26 MiB
29
+ - 0.265s
30
+
31
+ The memory result matches the implementation change: the previous version held roughly one final XML payload in Rust plus one Python ``bytes`` payload, while the current version writes into the Python ``bytes`` object directly.
32
+
33
+ Methodology
34
+ -----------
35
+
36
+ The benchmark uses ``benchmark_memory_rust.py`` with a deterministic generated payload so the Rust fast path can be measured without file parsing or pure-Python fallback behavior.
37
+
38
+ * Machine: Apple Silicon arm64
39
+ * OS: macOS 26.5
40
+ * Python: 3.14.0
41
+ * Build: ``python3 -m maturin develop --release --offline``
42
+ * Payload: 100,000 nested records
43
+ * Input JSON size: 44.31 MiB
44
+ * Output XML size: 78.17 MiB
45
+ * Measurement: process ``ru_maxrss`` after payload creation versus peak after ``json2xml_rs.dicttoxml(payload, attr_type=True)``
46
+ * Sampling: three fresh Python processes per version
47
+
48
+ The baseline RSS is captured after the large Python payload is already built. The reported serializer delta is ``peak_rss - baseline_rss``, which focuses the comparison on output construction rather than payload allocation.
49
+
50
+ Raw Samples
51
+ -----------
52
+
53
+ .. list-table::
54
+ :header-rows: 1
55
+ :widths: 24 18 18 18 18
56
+
57
+ * - Run
58
+ - Baseline RSS
59
+ - Peak RSS
60
+ - Serializer delta
61
+ - Time
62
+ * - previous-release-1
63
+ - 191.53 MiB
64
+ - 349.22 MiB
65
+ - 157.69 MiB
66
+ - 0.182s
67
+ * - previous-release-2
68
+ - 191.39 MiB
69
+ - 349.09 MiB
70
+ - 157.70 MiB
71
+ - 0.179s
72
+ * - previous-release-3
73
+ - 191.44 MiB
74
+ - 349.14 MiB
75
+ - 157.70 MiB
76
+ - 0.178s
77
+ * - current-release-1
78
+ - 191.45 MiB
79
+ - 271.77 MiB
80
+ - 80.31 MiB
81
+ - 0.265s
82
+ * - current-release-2
83
+ - 191.48 MiB
84
+ - 271.64 MiB
85
+ - 80.16 MiB
86
+ - 0.272s
87
+ * - current-release-3
88
+ - 191.25 MiB
89
+ - 271.55 MiB
90
+ - 80.30 MiB
91
+ - 0.258s
92
+
93
+ Tradeoff
94
+ --------
95
+
96
+ The memory improvement comes with a throughput cost in this release benchmark. Average conversion time increased from 0.180s to 0.265s, about **47.5% slower** for this payload.
97
+
98
+ That cost is likely from routing every XML write through ``std::io::Write`` and PyO3's bytes writer. The memory win is substantial for large outputs, but latency-sensitive callers may want more timing data before treating the bytes-writer path as a universal improvement.
99
+
100
+ Reproduction
101
+ ------------
102
+
103
+ Run each version in a fresh process after installing the desired Rust extension build.
104
+
105
+ .. code-block:: bash
106
+
107
+ python3 -m maturin develop --release --offline
108
+ python3 benchmark_memory_rust.py --records 100000 --label current-release-1
109
+
110
+ For the previous comparison, install commit ``7dd86b0`` in a temporary worktree, then run the same command from the main checkout so the benchmark script stays identical.