Commit aed8830a authored by Raymond Hettinger's avatar Raymond Hettinger

Add a fast path (no iterator creation) for a common case for repeating deques of size 1

parent 02697771
...@@ -654,6 +654,15 @@ class TestBasic(unittest.TestCase): ...@@ -654,6 +654,15 @@ class TestBasic(unittest.TestCase):
self.assertNotEqual(id(d), id(e)) self.assertNotEqual(id(d), id(e))
self.assertEqual(list(d), list(e)) self.assertEqual(list(d), list(e))
for i in range(5):
for maxlen in range(-1, 6):
s = [random.random() for j in range(i)]
d = deque(s) if maxlen == -1 else deque(s, maxlen)
e = d.copy()
self.assertEqual(d, e)
self.assertEqual(d.maxlen, e.maxlen)
self.assertTrue(all(x is y for x, y in zip(d, e)))
def test_copy_method(self): def test_copy_method(self):
mut = [10] mut = [10]
d = deque([mut]) d = deque([mut])
......
...@@ -1211,6 +1211,7 @@ deque_traverse(dequeobject *deque, visitproc visit, void *arg) ...@@ -1211,6 +1211,7 @@ deque_traverse(dequeobject *deque, visitproc visit, void *arg)
static PyObject * static PyObject *
deque_copy(PyObject *deque) deque_copy(PyObject *deque)
{ {
dequeobject *old_deque = (dequeobject *)deque;
if (Py_TYPE(deque) == &deque_type) { if (Py_TYPE(deque) == &deque_type) {
dequeobject *new_deque; dequeobject *new_deque;
PyObject *rv; PyObject *rv;
...@@ -1218,8 +1219,14 @@ deque_copy(PyObject *deque) ...@@ -1218,8 +1219,14 @@ deque_copy(PyObject *deque)
new_deque = (dequeobject *)deque_new(&deque_type, (PyObject *)NULL, (PyObject *)NULL); new_deque = (dequeobject *)deque_new(&deque_type, (PyObject *)NULL, (PyObject *)NULL);
if (new_deque == NULL) if (new_deque == NULL)
return NULL; return NULL;
new_deque->maxlen = ((dequeobject *)deque)->maxlen; new_deque->maxlen = old_deque->maxlen;
rv = deque_extend(new_deque, deque); /* Fast path for the deque_repeat() common case where len(deque) == 1 */
if (Py_SIZE(deque) == 1 && new_deque->maxlen != 0) {
PyObject *item = old_deque->leftblock->data[old_deque->leftindex];
rv = deque_append(new_deque, item);
} else {
rv = deque_extend(new_deque, deque);
}
if (rv != NULL) { if (rv != NULL) {
Py_DECREF(rv); Py_DECREF(rv);
return (PyObject *)new_deque; return (PyObject *)new_deque;
...@@ -1227,11 +1234,11 @@ deque_copy(PyObject *deque) ...@@ -1227,11 +1234,11 @@ deque_copy(PyObject *deque)
Py_DECREF(new_deque); Py_DECREF(new_deque);
return NULL; return NULL;
} }
if (((dequeobject *)deque)->maxlen == -1) if (old_deque->maxlen == -1)
return PyObject_CallFunction((PyObject *)(Py_TYPE(deque)), "O", deque, NULL); return PyObject_CallFunction((PyObject *)(Py_TYPE(deque)), "O", deque, NULL);
else else
return PyObject_CallFunction((PyObject *)(Py_TYPE(deque)), "Oi", return PyObject_CallFunction((PyObject *)(Py_TYPE(deque)), "Oi",
deque, ((dequeobject *)deque)->maxlen, NULL); deque, old_deque->maxlen, NULL);
} }
PyDoc_STRVAR(copy_doc, "Return a shallow copy of a deque."); PyDoc_STRVAR(copy_doc, "Return a shallow copy of a deque.");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment