Issue #25869: Optimized deepcopying ElementTree; it is now 20 times faster.
This commit is contained in:
parent
22adf2ac02
commit
060ed718ce
|
@ -115,6 +115,8 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #25869: Optimized deepcopying ElementTree; it is now 20 times faster.
|
||||||
|
|
||||||
- Issue #25873: Optimized iterating ElementTree. Iterating elements
|
- Issue #25873: Optimized iterating ElementTree. Iterating elements
|
||||||
Element.iter() is now 40% faster, iterating text Element.itertext()
|
Element.iter() is now 40% faster, iterating text Element.itertext()
|
||||||
is now up to 2.5 times faster.
|
is now up to 2.5 times faster.
|
||||||
|
|
|
@ -128,30 +128,6 @@ elementtree_free(void *m)
|
||||||
|
|
||||||
/* helpers */
|
/* 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*)
|
LOCAL(PyObject*)
|
||||||
list_join(PyObject* list)
|
list_join(PyObject* list)
|
||||||
{
|
{
|
||||||
|
@ -748,6 +724,9 @@ _elementtree_Element___copy___impl(ElementObject *self)
|
||||||
return (PyObject*) element;
|
return (PyObject*) element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Helper for a deep copy. */
|
||||||
|
LOCAL(PyObject *) deepcopy(PyObject *, PyObject *);
|
||||||
|
|
||||||
/*[clinic input]
|
/*[clinic input]
|
||||||
_elementtree.Element.__deepcopy__
|
_elementtree.Element.__deepcopy__
|
||||||
|
|
||||||
|
@ -838,6 +817,57 @@ _elementtree_Element___deepcopy__(ElementObject *self, PyObject *memo)
|
||||||
return NULL;
|
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]
|
/*[clinic input]
|
||||||
_elementtree.Element.__sizeof__ -> Py_ssize_t
|
_elementtree.Element.__sizeof__ -> Py_ssize_t
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue