[Python-checkins] cpython: Issue #25869: Optimized deepcopying ElementTree; it is now 20 times faster.
serhiy.storchaka
python-checkins at python.org
Mon Dec 21 05:57:53 EST 2015
https://hg.python.org/cpython/rev/090c3e3a648d
changeset: 99656:090c3e3a648d
user: Serhiy Storchaka <storchaka at gmail.com>
date: Mon Dec 21 12:57:27 2015 +0200
summary:
Issue #25869: Optimized deepcopying ElementTree; it is now 20 times faster.
files:
Misc/NEWS | 2 +
Modules/_elementtree.c | 78 ++++++++++++++++++++---------
2 files changed, 56 insertions(+), 24 deletions(-)
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -115,6 +115,8 @@
Library
-------
+- Issue #25869: Optimized deepcopying ElementTree; it is now 20 times faster.
+
- Issue #25873: Optimized iterating ElementTree. Iterating elements
Element.iter() is now 40% faster, iterating text Element.itertext()
is now up to 2.5 times faster.
diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c
--- a/Modules/_elementtree.c
+++ b/Modules/_elementtree.c
@@ -129,30 +129,6 @@
/* helpers */
LOCAL(PyObject*)
-deepcopy(PyObject* object, PyObject* memo)
-{
- /* do a deep copy of the given object */
- PyObject* args;
- PyObject* result;
- elementtreestate *st = ET_STATE_GLOBAL;
-
- if (!st->deepcopy_obj) {
- PyErr_SetString(
- PyExc_RuntimeError,
- "deepcopy helper not found"
- );
- return NULL;
- }
-
- args = PyTuple_Pack(2, object, memo);
- if (!args)
- return NULL;
- result = PyObject_CallObject(st->deepcopy_obj, args);
- Py_DECREF(args);
- return result;
-}
-
-LOCAL(PyObject*)
list_join(PyObject* list)
{
/* join list elements (destroying the list in the process) */
@@ -748,6 +724,9 @@
return (PyObject*) element;
}
+/* Helper for a deep copy. */
+LOCAL(PyObject *) deepcopy(PyObject *, PyObject *);
+
/*[clinic input]
_elementtree.Element.__deepcopy__
@@ -838,6 +817,57 @@
return NULL;
}
+LOCAL(PyObject *)
+deepcopy(PyObject *object, PyObject *memo)
+{
+ /* do a deep copy of the given object */
+ PyObject *args;
+ PyObject *result;
+ elementtreestate *st;
+
+ /* Fast paths */
+ if (object == Py_None || PyUnicode_CheckExact(object)) {
+ Py_INCREF(object);
+ return object;
+ }
+
+ if (Py_REFCNT(object) == 1) {
+ if (PyDict_CheckExact(object)) {
+ PyObject *key, *value;
+ Py_ssize_t pos = 0;
+ int simple = 1;
+ while (PyDict_Next(object, &pos, &key, &value)) {
+ if (!PyUnicode_CheckExact(key) || !PyUnicode_CheckExact(value)) {
+ simple = 0;
+ break;
+ }
+ }
+ if (simple)
+ return PyDict_Copy(object);
+ /* Fall through to general case */
+ }
+ else if (Element_CheckExact(object)) {
+ return _elementtree_Element___deepcopy__((ElementObject *)object, memo);
+ }
+ }
+
+ /* General case */
+ st = ET_STATE_GLOBAL;
+ if (!st->deepcopy_obj) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "deepcopy helper not found");
+ return NULL;
+ }
+
+ args = PyTuple_Pack(2, object, memo);
+ if (!args)
+ return NULL;
+ result = PyObject_CallObject(st->deepcopy_obj, args);
+ Py_DECREF(args);
+ return result;
+}
+
+
/*[clinic input]
_elementtree.Element.__sizeof__ -> Py_ssize_t
--
Repository URL: https://hg.python.org/cpython
More information about the Python-checkins
mailing list