Skip to content

Commit 2a570af

Browse files
authored
bpo-37587: optimize json.loads (GH-15134)
Use a tighter scope temporary variable to help register allocation. 1% speedup for large string. Use PyDict_SetItemDefault() for memoizing keys. At most 4% speedup when the cache hit ratio is low.
1 parent e43e7ed commit 2a570af

File tree

1 file changed

+19
-20
lines changed

1 file changed

+19
-20
lines changed

Modules/_json.c

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -433,16 +433,21 @@ scanstring_unicode(PyObject *pystr, Py_ssize_t end, int strict, Py_ssize_t *next
433433
}
434434
while (1) {
435435
/* Find the end of the string or the next escape */
436-
Py_UCS4 c = 0;
437-
for (next = end; next < len; next++) {
438-
c = PyUnicode_READ(kind, buf, next);
439-
if (c == '"' || c == '\\') {
440-
break;
441-
}
442-
else if (c <= 0x1f && strict) {
443-
raise_errmsg("Invalid control character at", pystr, next);
444-
goto bail;
436+
Py_UCS4 c;
437+
{
438+
// Use tight scope variable to help register allocation.
439+
Py_UCS4 d = 0;
440+
for (next = end; next < len; next++) {
441+
d = PyUnicode_READ(kind, buf, next);
442+
if (d == '"' || d == '\\') {
443+
break;
444+
}
445+
if (d <= 0x1f && strict) {
446+
raise_errmsg("Invalid control character at", pystr, next);
447+
goto bail;
448+
}
445449
}
450+
c = d;
446451
}
447452
if (!(c == '"' || c == '\\')) {
448453
raise_errmsg("Unterminated string starting at", pystr, begin);
@@ -749,19 +754,13 @@ _parse_object_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ss
749754
key = scanstring_unicode(pystr, idx + 1, s->strict, &next_idx);
750755
if (key == NULL)
751756
goto bail;
752-
memokey = PyDict_GetItemWithError(s->memo, key);
753-
if (memokey != NULL) {
754-
Py_INCREF(memokey);
755-
Py_DECREF(key);
756-
key = memokey;
757-
}
758-
else if (PyErr_Occurred()) {
757+
memokey = PyDict_SetDefault(s->memo, key, key);
758+
if (memokey == NULL) {
759759
goto bail;
760760
}
761-
else {
762-
if (PyDict_SetItem(s->memo, key, key) < 0)
763-
goto bail;
764-
}
761+
Py_INCREF(memokey);
762+
Py_DECREF(key);
763+
key = memokey;
765764
idx = next_idx;
766765

767766
/* skip whitespace between key and : delimiter, read :, skip whitespace */

0 commit comments

Comments
 (0)