json: make "memo" dict local to scan_once call
Feature or enhancement
The Modules/_json.c parser is mostly stateless (or the state is immutable). The one exception is the "memo" dictionary, which is used to avoid duplicate PyUnicodeObject instances for the same JSON C strings.
| memokey = PyDict_SetDefault(s->memo, key, key); | |
| if (memokey == NULL) { | |
| goto bail; | |
| } | |
| Py_SETREF(key, Py_NewRef(memokey)); |
The memo dictionary is already cleared after each call scan_once:
| PyDict_Clear(self->memo); |
We should move the creation and destruction of the memo dict to the invocation of scan_once instead of having it as part of the module state. This will avoid contention on the dictionary locks in --disable-gil builds if multiple threads are concurrently parsing JSON strings.
For an example modification, see colesbury/nogil-3.12@964bb33962.