Commit 6fe39b76 authored by Serhiy Storchaka's avatar Serhiy Storchaka

Issue #17897: Optimized unpickle prefetching.

parent cc6e87b2
...@@ -18,6 +18,8 @@ Core and Builtins ...@@ -18,6 +18,8 @@ Core and Builtins
Library Library
------- -------
- Issue #17897: Optimized unpickle prefetching.
- Issue #3693: Make the error message more helpful when the array.array() - Issue #3693: Make the error message more helpful when the array.array()
constructor is given a str. Move the array module typecode documentation to constructor is given a str. Move the array module typecode documentation to
the docstring of the constructor. the docstring of the constructor.
......
...@@ -1121,7 +1121,7 @@ static Py_ssize_t ...@@ -1121,7 +1121,7 @@ static Py_ssize_t
_Unpickler_ReadFromFile(UnpicklerObject *self, Py_ssize_t n) _Unpickler_ReadFromFile(UnpicklerObject *self, Py_ssize_t n)
{ {
PyObject *data; PyObject *data;
Py_ssize_t read_size, prefetched_size = 0; Py_ssize_t read_size;
assert(self->read != NULL); assert(self->read != NULL);
...@@ -1134,46 +1134,38 @@ _Unpickler_ReadFromFile(UnpicklerObject *self, Py_ssize_t n) ...@@ -1134,46 +1134,38 @@ _Unpickler_ReadFromFile(UnpicklerObject *self, Py_ssize_t n)
Py_DECREF(empty_tuple); Py_DECREF(empty_tuple);
} }
else { else {
PyObject *len = PyLong_FromSsize_t(n); PyObject *len;
if (len == NULL) /* Prefetch some data without advancing the file pointer, if possible */
return -1; if (self->peek && n < PREFETCH) {
data = _Pickle_FastCall(self->read, len); len = PyLong_FromSsize_t(PREFETCH);
} if (len == NULL)
if (data == NULL) return -1;
return -1; data = _Pickle_FastCall(self->peek, len);
if (data == NULL) {
/* Prefetch some data without advancing the file pointer, if possible */ if (!PyErr_ExceptionMatches(PyExc_NotImplementedError))
if (self->peek) { return -1;
PyObject *len, *prefetched;
len = PyLong_FromSsize_t(PREFETCH);
if (len == NULL) {
Py_DECREF(data);
return -1;
}
prefetched = _Pickle_FastCall(self->peek, len);
if (prefetched == NULL) {
if (PyErr_ExceptionMatches(PyExc_NotImplementedError)) {
/* peek() is probably not supported by the given file object */ /* peek() is probably not supported by the given file object */
PyErr_Clear(); PyErr_Clear();
Py_CLEAR(self->peek); Py_CLEAR(self->peek);
} }
else { else {
read_size = _Unpickler_SetStringInput(self, data);
Py_DECREF(data); Py_DECREF(data);
return -1; self->prefetched_idx = 0;
if (n <= read_size)
return n;
} }
} }
else { len = PyLong_FromSsize_t(n);
assert(PyBytes_Check(prefetched)); if (len == NULL)
prefetched_size = PyBytes_GET_SIZE(prefetched); return -1;
PyBytes_ConcatAndDel(&data, prefetched); data = _Pickle_FastCall(self->read, len);
if (data == NULL)
return -1;
}
} }
if (data == NULL)
return -1;
read_size = _Unpickler_SetStringInput(self, data) - prefetched_size; read_size = _Unpickler_SetStringInput(self, data);
Py_DECREF(data); Py_DECREF(data);
self->prefetched_idx = read_size;
return read_size; return read_size;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment