speed up unpickling

refer python/cpython@bee09aecc2
This commit is contained in:
ahgamut 2021-11-09 00:49:52 +05:30
parent ed44f3b14d
commit 4802173eba
2 changed files with 49 additions and 23 deletions

View file

@ -1465,12 +1465,16 @@ class _Unpickler:
def load_appends(self): def load_appends(self):
items = self.pop_mark() items = self.pop_mark()
list_obj = self.stack[-1] list_obj = self.stack[-1]
if isinstance(list_obj, list): try:
list_obj.extend(items) extend = list_obj.extend
except AttributeError:
pass
else: else:
append = list_obj.append extend(items)
for item in items: return
append(item) append = list_obj.append
for item in items:
append(item)
dispatch[APPENDS[0]] = load_appends dispatch[APPENDS[0]] = load_appends
def load_setitem(self): def load_setitem(self):

View file

@ -5946,6 +5946,8 @@ static int
do_append(UnpicklerObject *self, Py_ssize_t x) do_append(UnpicklerObject *self, Py_ssize_t x)
{ {
PyObject *value; PyObject *value;
PyObject *slice;
PyObject *result;
PyObject *list; PyObject *list;
Py_ssize_t len, i; Py_ssize_t len, i;
@ -5957,8 +5959,7 @@ do_append(UnpicklerObject *self, Py_ssize_t x)
list = self->stack->data[x - 1]; list = self->stack->data[x - 1];
if (PyList_Check(list)) { if (PyList_CheckExact(list)) {
PyObject *slice;
Py_ssize_t list_len; Py_ssize_t list_len;
int ret; int ret;
@ -5971,27 +5972,48 @@ do_append(UnpicklerObject *self, Py_ssize_t x)
return ret; return ret;
} }
else { else {
PyObject *append_func; PyObject *extend_func;
_Py_IDENTIFIER(append); _Py_IDENTIFIER(extend);
append_func = _PyObject_GetAttrId(list, &PyId_append); extend_func = _PyObject_GetAttrId(list, &PyId_extend);
if (append_func == NULL) if (extend_func != NULL) {
return -1; slice = Pdata_poplist(self->stack, x);
for (i = x; i < len; i++) { if (!slice) {
PyObject *result; Py_DECREF(extend_func);
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; return -1;
} }
result = _Pickle_FastCall(extend_func, slice);
Py_DECREF(slice);
Py_DECREF(extend_func);
if (result == NULL)
return -1;
Py_DECREF(result); Py_DECREF(result);
} }
Py_SIZE(self->stack) = x; else {
Py_DECREF(append_func); 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; return 0;