You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Float encoding is a particularly weak area for the json library, especially for large-magnitude floats. Would it be possible to optimize this by adding a special case to PyUnicodeWriter_WriteRepr(), similar to _PyLong_FormatWriter() for integers?
A fast path in PyUnicodeWriter_WriteRepr seems reasonable, but would not help a lot (I did a quick benchmark, only about 10% depending on the type of floats). A faster float-to-str would help more. There are algorithms for it, but not readily available in C. See https://discuss.python.org/t/faster-float-to-string-conversions/107397
@vstinner and I discussed this at the sprint that we are going to measure general benchmark how much this call paths are executed and adding the fast path.
I added the int fast-path in #125214 which contains benchmark results: it was between 1.54x and 1.93x faster on repr(list) depending on the list size (between 3 and 50 items).
FYI I added the str fast-path in #133969 which also contains benchmark results (1.18x faster in average, up to 1.61x faster in the best case).
In the past, I considered to add a type slot (like PyTypeObject.tp_str_writer and/or PyTypeObject.tp_repr_writer) instead of using hardcoded fast paths. If we add multiple fast paths in the future, we might reconsider adding a type slot?
pyperformance would not be a good benchmark for adding this fast path: 0% of calls.
But even in the standard library test suite:
Argument type
Calls
Share
Note
exact int
2,924,088
86.7%
existing fast path (_PyLong_FormatWriter)
None
181,066
5.4%
exact list
69,501
2.1%
other types
58,946
1.7%
user classes, type objects, etc.
exact str
58,158
1.7%
exact dict
40,537
1.2%
bool
20,759
0.6%
exact float
10,657
0.32%
proposed fast path
exact bytes
5,700
0.2%
exact tuple
2,244
0.07%
total
3,371,663
100%
So I am -1 unless we can provide a benchmark that justifies this fast path, and even then float would not be the first candidate, since it is lower than str and dict.
PyUnicode_Format() calls formatfloat() for %f (and other similar formats): it calls PyOS_double_to_string() + _PyUnicodeWriter_WriteASCIIString().
float.__float__() calls _PyFloat_FormatAdvancedWriter() which is implemented with PyOS_double_to_string() + _PyUnicodeWriter_WriteASCIIString() for the common case.
Activity
eendebakpt commentedon Oct 19, 2026
A fast path in
PyUnicodeWriter_WriteReprseems reasonable, but would not help a lot (I did a quick benchmark, only about 10% depending on the type of floats). A faster float-to-str would help more. There are algorithms for it, but not readily available in C. See https://discuss.python.org/t/faster-float-to-string-conversions/107397corona10 commentedon Oct 19, 2026
@eendebakpt @nineteendo
@vstinner and I discussed this at the sprint that we are going to measure general benchmark how much this call paths are executed and adding the fast path.
vstinner commentedon Oct 19, 2026
I added the int fast-path in #125214 which contains benchmark results: it was between 1.54x and 1.93x faster on repr(list) depending on the list size (between 3 and 50 items).
FYI I added the str fast-path in #133969 which also contains benchmark results (1.18x faster in average, up to 1.61x faster in the best case).
vstinner commentedon Oct 19, 2026
In the past, I considered to add a type slot (like
PyTypeObject.tp_str_writerand/orPyTypeObject.tp_repr_writer) instead of using hardcoded fast paths. If we add multiple fast paths in the future, we might reconsider adding a type slot?corona10 commentedon Oct 19, 2026
_PyLong_FormatWriter)So I am -1 unless we can provide a benchmark that justifies this fast path, and even then float would not be the first candidate, since it is lower than str and dict.
vstinner commentedon Oct 20, 2026
If floats are more common in json than in general in Python, json can add a fast-path for float using the internal C API.
The
_jsonextension already has a code path forfloatwhich gets aPyUnicodeWriter:vstinner commentedon Oct 20, 2026
PyUnicode_Format()callsformatfloat()for%f(and other similar formats): it callsPyOS_double_to_string()+_PyUnicodeWriter_WriteASCIIString().float.__float__()calls_PyFloat_FormatAdvancedWriter()which is implemented withPyOS_double_to_string()+_PyUnicodeWriter_WriteASCIIString()for the common case.PyUnicode_FromFormat()doesn't support%fformat.pythongh-159702: Add fast-path for float in _json encoder
vstinner commentedon Oct 20, 2026
I wrote PR gh-159826 to do that. It calls
PyOS_double_to_string()+PyUnicodeWriter_WriteASCII()(functions of the public C API).vstinner commentedon Oct 20, 2026
@nineteendo: Would it be possible for you to re-run your benchmark on my PR?
Oh crap, I wrote #156897 (JSON float optimization for
json.loads()) last month, but I usedgit push --forceand so lost my work :-(See also issue gh-150638.