Skip to content

Commit 920e20b

Browse files
committed
Update performance benchmark and results
1 parent 064e492 commit 920e20b

File tree

3 files changed

+20
-31
lines changed

3 files changed

+20
-31
lines changed

README.md

Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@
2424
- [Is there a `dumps`, `write` or `encode` function?](#is-there-a-dumps-write-or-encode-function)
2525
- [How do TOML types map into Python types?](#how-do-toml-types-map-into-python-types)
2626
- [Performance](#performance)
27-
- [Pure Python](#pure-python)
2827
- [Mypyc generated wheel](#mypyc-generated-wheel)
28+
- [Pure Python](#pure-python)
2929

3030
<!-- mdformat-toc end -->
3131

@@ -156,7 +156,7 @@ tomllib.loads("['This parses fine with Python 3.6+']")
156156
- it's lil'
157157
- pure Python with zero dependencies
158158
- the fastest pure Python parser [\*](#pure-python):
159-
18x as fast as [tomlkit](https://pypi.org/project/tomlkit/),
159+
14x as fast as [tomlkit](https://pypi.org/project/tomlkit/),
160160
2.1x as fast as [toml](https://pypi.org/project/toml/)
161161
- outputs [basic data types](#how-do-toml-types-map-into-python-types) only
162162
- 100% spec compliant: passes all tests in
@@ -202,47 +202,42 @@ The core library does not include write capability, as most TOML use cases are r
202202

203203
The `benchmark/` folder in this repository contains a performance benchmark for comparing the various Python TOML parsers.
204204

205-
Below are the results for commit [0724e2a](https://github.com/hukkin/tomli/tree/0724e2ab1858da7f5e05a9bffdb24c33589d951c).
205+
Below are the results for commit [064e492](https://github.com/hukkin/tomli/tree/064e492919b2338def788753b8c981c9131334c0).
206206

207-
### Pure Python<a name="pure-python"></a>
207+
### Mypyc generated wheel<a name="mypyc-generated-wheel"></a>
208208

209209
```console
210210
foo@bar:~/dev/tomli$ python --version
211-
Python 3.12.7
211+
Python 3.14.2
212212
foo@bar:~/dev/tomli$ pip freeze
213-
attrs==21.4.0
214-
click==8.1.7
215-
pytomlpp==1.0.13
216-
qtoml==0.3.1
217-
rtoml==0.11.0
213+
pytomlpp==1.1.0
214+
rtoml==0.13.0
218215
toml==0.10.2
219216
tomli @ file:///home/foo/dev/tomli
220-
tomlkit==0.13.2
217+
tomlkit==0.13.3
221218
foo@bar:~/dev/tomli$ python benchmark/run.py
222219
Parsing data.toml 5000 times:
223220
------------------------------------------------------
224221
parser | exec time | performance (more is better)
225222
-----------+------------+-----------------------------
226-
rtoml | 0.647 s | baseline (100%)
227-
pytomlpp | 0.891 s | 72.62%
228-
tomli | 3.14 s | 20.56%
229-
toml | 6.69 s | 9.67%
230-
qtoml | 8.27 s | 7.82%
231-
tomlkit | 56.1 s | 1.15%
223+
rtoml | 0.328 s | baseline (100%)
224+
pytomlpp | 0.365 s | 89.75%
225+
tomli | 0.838 s | 39.12%
226+
toml | 3.01 s | 10.90%
227+
tomlkit | 20.7 s | 1.59%
232228
```
233229

234-
### Mypyc generated wheel<a name="mypyc-generated-wheel"></a>
230+
### Pure Python<a name="pure-python"></a>
235231

236232
```console
237233
foo@bar:~/dev/tomli$ python benchmark/run.py
238234
Parsing data.toml 5000 times:
239235
------------------------------------------------------
240236
parser | exec time | performance (more is better)
241237
-----------+------------+-----------------------------
242-
rtoml | 0.668 s | baseline (100%)
243-
pytomlpp | 0.893 s | 74.81%
244-
tomli | 1.96 s | 34.18%
245-
toml | 6.64 s | 10.07%
246-
qtoml | 8.26 s | 8.09%
247-
tomlkit | 52.9 s | 1.26%
238+
rtoml | 0.323 s | baseline (100%)
239+
pytomlpp | 0.365 s | 88.40%
240+
tomli | 1.44 s | 22.36%
241+
toml | 3.03 s | 10.65%
242+
tomlkit | 20.6 s | 1.57%
248243
```

benchmark/requirements.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,4 @@
55
pytomlpp
66
toml
77
tomlkit
8-
qtoml
98
rtoml

benchmark/run.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import timeit
66

77
import pytomlpp
8-
import qtoml
98
import rtoml
109
import toml
1110
import tomlkit
@@ -22,7 +21,7 @@ def benchmark(
2221
) -> float:
2322
placeholder = "Running..."
2423
print(f"{name:>{col_width[0]}} | {placeholder}", end="", flush=True)
25-
time_taken = timeit.timeit(func, number=run_count)
24+
time_taken = min(timeit.repeat(func, number=run_count, repeat=5))
2625
print("\b" * len(placeholder), end="")
2726
time_suffix = " s"
2827
print(f"{time_taken:{col_width[1]-len(time_suffix)}.3g}{time_suffix}", end="")
@@ -39,9 +38,6 @@ def run(run_count: int) -> None:
3938
data_path = Path(__file__).parent / "data.toml"
4039
test_data = data_path.read_bytes().decode()
4140

42-
# qtoml has a bug making it crash without this newline normalization
43-
test_data = test_data.replace("\r\n", "\n")
44-
4541
col_width = (10, 10, 28)
4642
col_head = ("parser", "exec time", "performance (more is better)")
4743
print(f"Parsing data.toml {run_count} times:")
@@ -55,7 +51,6 @@ def run(run_count: int) -> None:
5551
benchmark("pytomlpp", run_count, lambda: pytomlpp.loads(test_data), col_width, compare_to=baseline) # noqa: E501
5652
benchmark("tomli", run_count, lambda: tomli.loads(test_data), col_width, compare_to=baseline) # noqa: E501
5753
benchmark("toml", run_count, lambda: toml.loads(test_data), col_width, compare_to=baseline) # noqa: E501
58-
benchmark("qtoml", run_count, lambda: qtoml.loads(test_data), col_width, compare_to=baseline) # noqa: E501
5954
benchmark("tomlkit", run_count, lambda: tomlkit.parse(test_data), col_width, compare_to=baseline) # noqa: E501
6055
# fmt: on
6156

0 commit comments

Comments
 (0)