summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2018-07-18 07:10:49 (GMT)
committerGitHub <noreply@github.com>2018-07-18 07:10:49 (GMT)
commit5d4cb54800966947db2e86f65fb109c5067076be (patch)
tree26156a09f429ef95392d06ee8ea99bcdf30dea38
parentfeabae961707b00008c15a31352e458f4e8b3a6c (diff)
downloadcpython-5d4cb54800966947db2e86f65fb109c5067076be.zip
cpython-5d4cb54800966947db2e86f65fb109c5067076be.tar.gz
cpython-5d4cb54800966947db2e86f65fb109c5067076be.tar.bz2
bpo-34141: Optimized pickling simple non-recursive values. (GH-8318)
-rw-r--r--Misc/NEWS.d/next/Core and Builtins/2018-07-18-08-36-58.bpo-34141.Fo7Q5r.rst1
-rw-r--r--Modules/_pickle.c36
2 files changed, 17 insertions, 20 deletions
diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-07-18-08-36-58.bpo-34141.Fo7Q5r.rst b/Misc/NEWS.d/next/Core and Builtins/2018-07-18-08-36-58.bpo-34141.Fo7Q5r.rst
new file mode 100644
index 0000000..328b109
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2018-07-18-08-36-58.bpo-34141.Fo7Q5r.rst
@@ -0,0 +1 @@
+Optimized pickling atomic types (None, bool, int, float, bytes, str).
diff --git a/Modules/_pickle.c b/Modules/_pickle.c
index aa672af..294f334 100644
--- a/Modules/_pickle.c
+++ b/Modules/_pickle.c
@@ -3940,9 +3940,6 @@ save(PicklerObject *self, PyObject *obj, int pers_save)
if (_Pickler_OpcodeBoundary(self) < 0)
return -1;
- if (Py_EnterRecursiveCall(" while pickling an object"))
- return -1;
-
/* The extra pers_save argument is necessary to avoid calling save_pers()
on its returned object. */
if (!pers_save && self->pers_func) {
@@ -3952,7 +3949,7 @@ save(PicklerObject *self, PyObject *obj, int pers_save)
1 if a persistent id was saved.
*/
if ((status = save_pers(self, obj)) != 0)
- goto done;
+ return status;
}
type = Py_TYPE(obj);
@@ -3965,40 +3962,39 @@ save(PicklerObject *self, PyObject *obj, int pers_save)
/* Atom types; these aren't memoized, so don't check the memo. */
if (obj == Py_None) {
- status = save_none(self, obj);
- goto done;
+ return save_none(self, obj);
}
else if (obj == Py_False || obj == Py_True) {
- status = save_bool(self, obj);
- goto done;
+ return save_bool(self, obj);
}
else if (type == &PyLong_Type) {
- status = save_long(self, obj);
- goto done;
+ return save_long(self, obj);
}
else if (type == &PyFloat_Type) {
- status = save_float(self, obj);
- goto done;
+ return save_float(self, obj);
}
/* Check the memo to see if it has the object. If so, generate
a GET (or BINGET) opcode, instead of pickling the object
once again. */
if (PyMemoTable_Get(self->memo, obj)) {
- if (memo_get(self, obj) < 0)
- goto error;
- goto done;
+ return memo_get(self, obj);
}
if (type == &PyBytes_Type) {
- status = save_bytes(self, obj);
- goto done;
+ return save_bytes(self, obj);
}
else if (type == &PyUnicode_Type) {
- status = save_unicode(self, obj);
- goto done;
+ return save_unicode(self, obj);
}
- else if (type == &PyDict_Type) {
+
+ /* We're only calling Py_EnterRecursiveCall here so that atomic
+ types above are pickled faster. */
+ if (Py_EnterRecursiveCall(" while pickling an object")) {
+ return -1;
+ }
+
+ if (type == &PyDict_Type) {
status = save_dict(self, obj);
goto done;
}