Skip to content

Commit 2259760

Browse files
committed
gh-150860: Skip the whitespace scan in json.loads() when there is none
decode() ran a whitespace-skipping regex at both ends of every document even though most have none. Skip the leading match when the document does not start with whitespace and the trailing match when the parse already consumed the whole string. Documents with surrounding whitespace keep the original behavior and output is unchanged.
1 parent b643826 commit 2259760

2 files changed

Lines changed: 12 additions & 3 deletions

File tree

Lib/json/decoder.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -355,10 +355,16 @@ def decode(self, s, _w=WHITESPACE.match):
355355
containing a JSON document).
356356
357357
"""
358-
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
359-
end = _w(s, end).end()
358+
# Skip the WHITESPACE.match() call (and its match-object allocation)
359+
# for the common case where there is no leading whitespace.
360+
idx = _w(s, 0).end() if s and s[0] in ' \t\n\r' else 0
361+
obj, end = self.raw_decode(s, idx=idx)
362+
# Likewise avoid the trailing-whitespace match when the parse already
363+
# consumed the whole string.
360364
if end != len(s):
361-
raise JSONDecodeError("Extra data", s, end)
365+
end = _w(s, end).end()
366+
if end != len(s):
367+
raise JSONDecodeError("Extra data", s, end)
362368
return obj
363369

364370
def raw_decode(self, s, idx=0):
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Speed up :func:`json.loads` for documents without leading or trailing
2+
whitespace by skipping the whitespace scan in that common case. Patch by Bernát
3+
Gábor.

0 commit comments

Comments
 (0)