From 4802173eba5108f1f4c950600322cd3f6b82850f Mon Sep 17 00:00:00 2001 From: ahgamut <41098605+ahgamut@users.noreply.github.com> Date: Tue, 9 Nov 2021 00:49:52 +0530 Subject: [PATCH] speed up unpickling refer python/cpython@bee09aecc2c31 --- third_party/python/Lib/pickle.py | 14 ++++--- third_party/python/Modules/_pickle.c | 58 +++++++++++++++++++--------- 2 files changed, 49 insertions(+), 23 deletions(-) diff --git a/third_party/python/Lib/pickle.py b/third_party/python/Lib/pickle.py index 54411616d..c89a28e85 100644 --- a/third_party/python/Lib/pickle.py +++ b/third_party/python/Lib/pickle.py @@ -1465,12 +1465,16 @@ class _Unpickler: def load_appends(self): items = self.pop_mark() list_obj = self.stack[-1] - if isinstance(list_obj, list): - list_obj.extend(items) + try: + extend = list_obj.extend + except AttributeError: + pass else: - append = list_obj.append - for item in items: - append(item) + extend(items) + return + append = list_obj.append + for item in items: + append(item) dispatch[APPENDS[0]] = load_appends def load_setitem(self): diff --git a/third_party/python/Modules/_pickle.c b/third_party/python/Modules/_pickle.c index aa815047e..e0b2f32a8 100644 --- a/third_party/python/Modules/_pickle.c +++ b/third_party/python/Modules/_pickle.c @@ -5946,6 +5946,8 @@ static int do_append(UnpicklerObject *self, Py_ssize_t x) { PyObject *value; + PyObject *slice; + PyObject *result; PyObject *list; Py_ssize_t len, i; @@ -5957,8 +5959,7 @@ do_append(UnpicklerObject *self, Py_ssize_t x) list = self->stack->data[x - 1]; - if (PyList_Check(list)) { - PyObject *slice; + if (PyList_CheckExact(list)) { Py_ssize_t list_len; int ret; @@ -5971,27 +5972,48 @@ do_append(UnpicklerObject *self, Py_ssize_t x) return ret; } else { - PyObject *append_func; - _Py_IDENTIFIER(append); + PyObject *extend_func; + _Py_IDENTIFIER(extend); - append_func = _PyObject_GetAttrId(list, &PyId_append); - if (append_func == NULL) - return -1; - for (i = x; i < len; i++) { - PyObject *result; - - value = self->stack->data[i]; - result = _Pickle_FastCall(append_func, value); - if (result == NULL) { - Pdata_clear(self->stack, i + 1); - Py_SIZE(self->stack) = x; - Py_DECREF(append_func); + extend_func = _PyObject_GetAttrId(list, &PyId_extend); + if (extend_func != NULL) { + slice = Pdata_poplist(self->stack, x); + if (!slice) { + Py_DECREF(extend_func); return -1; } + result = _Pickle_FastCall(extend_func, slice); + Py_DECREF(slice); + Py_DECREF(extend_func); + if (result == NULL) + return -1; Py_DECREF(result); } - Py_SIZE(self->stack) = x; - Py_DECREF(append_func); + else { + PyObject *append_func; + _Py_IDENTIFIER(append); + + /* Even if the PEP 307 requires extend() and append() methods, + fall back on append() if the object has no extend() method + for backward compatibility. */ + PyErr_Clear(); + append_func = _PyObject_GetAttrId(list, &PyId_append); + if (append_func == NULL) + return -1; + for (i = x; i < len; i++) { + value = self->stack->data[i]; + result = _Pickle_FastCall(append_func, value); + if (result == NULL) { + Pdata_clear(self->stack, i + 1); + Py_SIZE(self->stack) = x; + Py_DECREF(append_func); + return -1; + } + Py_DECREF(result); + } + Py_SIZE(self->stack) = x; + Py_DECREF(append_func); + } } return 0;