[Python-checkins] cpython: Issue #17897: Optimized unpickle prefetching.

serhiy.storchaka python-checkins at python.org
Sat Nov 30 22:16:13 CET 2013


http://hg.python.org/cpython/rev/d565310e7ae3
changeset:   87654:d565310e7ae3
user:        Serhiy Storchaka <storchaka at gmail.com>
date:        Sat Nov 30 23:15:38 2013 +0200
summary:
  Issue #17897: Optimized unpickle prefetching.

files:
  Misc/NEWS         |   2 +
  Modules/_pickle.c |  56 +++++++++++++++--------------------
  2 files changed, 26 insertions(+), 32 deletions(-)


diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -18,6 +18,8 @@
 Library
 -------
 
+- Issue #17897: Optimized unpickle prefetching.
+
 - Issue #3693: Make the error message more helpful when the array.array()
   constructor is given a str. Move the array module typecode documentation to
   the docstring of the constructor.
diff --git a/Modules/_pickle.c b/Modules/_pickle.c
--- a/Modules/_pickle.c
+++ b/Modules/_pickle.c
@@ -1121,7 +1121,7 @@
 _Unpickler_ReadFromFile(UnpicklerObject *self, Py_ssize_t n)
 {
     PyObject *data;
-    Py_ssize_t read_size, prefetched_size = 0;
+    Py_ssize_t read_size;
 
     assert(self->read != NULL);
 
@@ -1134,46 +1134,38 @@
         Py_DECREF(empty_tuple);
     }
     else {
-        PyObject *len = PyLong_FromSsize_t(n);
-        if (len == NULL)
-            return -1;
-        data = _Pickle_FastCall(self->read, len);
-    }
-    if (data == NULL)
-        return -1;
-
-    /* Prefetch some data without advancing the file pointer, if possible */
-    if (self->peek) {
-        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)) {
+        PyObject *len;
+        /* Prefetch some data without advancing the file pointer, if possible */
+        if (self->peek && n < PREFETCH) {
+            len = PyLong_FromSsize_t(PREFETCH);
+            if (len == NULL)
+                return -1;
+            data = _Pickle_FastCall(self->peek, len);
+            if (data == NULL) {
+                if (!PyErr_ExceptionMatches(PyExc_NotImplementedError))
+                    return -1;
                 /* peek() is probably not supported by the given file object */
                 PyErr_Clear();
                 Py_CLEAR(self->peek);
             }
             else {
+                read_size = _Unpickler_SetStringInput(self, data);
                 Py_DECREF(data);
-                return -1;
+                self->prefetched_idx = 0;
+                if (n <= read_size)
+                    return n;
             }
         }
-        else {
-            assert(PyBytes_Check(prefetched));
-            prefetched_size = PyBytes_GET_SIZE(prefetched);
-            PyBytes_ConcatAndDel(&data, prefetched);
-            if (data == NULL)
-                return -1;
-        }
-    }
-
-    read_size = _Unpickler_SetStringInput(self, data) - prefetched_size;
+        len = PyLong_FromSsize_t(n);
+        if (len == NULL)
+            return -1;
+        data = _Pickle_FastCall(self->read, len);
+    }
+    if (data == NULL)
+        return -1;
+
+    read_size = _Unpickler_SetStringInput(self, data);
     Py_DECREF(data);
-    self->prefetched_idx = read_size;
     return read_size;
 }
 

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list