]> granicus.if.org Git - python/commitdiff
Issue #17897: Optimized unpickle prefetching.
authorSerhiy Storchaka <storchaka@gmail.com>
Sat, 30 Nov 2013 21:15:38 +0000 (23:15 +0200)
committerSerhiy Storchaka <storchaka@gmail.com>
Sat, 30 Nov 2013 21:15:38 +0000 (23:15 +0200)
Misc/NEWS
Modules/_pickle.c

index 09d2516b1a6fc2b7f83f6ddd74144b08d25a27f8..653b0f4326085300f183f69db43b7c3ef9296a48 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -18,6 +18,8 @@ Core and Builtins
 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.
index 6271c4b33a41b663128e341fae8b895b019f22f7..a9fad0e94952f3fc35df42ca03d1d5f07c4c6e73 100644 (file)
@@ -1121,7 +1121,7 @@ static Py_ssize_t
 _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 @@ _Unpickler_ReadFromFile(UnpicklerObject *self, Py_ssize_t n)
         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;
-        }
+        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) - prefetched_size;
+    read_size = _Unpickler_SetStringInput(self, data);
     Py_DECREF(data);
-    self->prefetched_idx = read_size;
     return read_size;
 }