Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit aed8830

Browse files
committed
Add a fast path (no iterator creation) for a common case for repeating deques of size 1
1 parent 0269777 commit aed8830

2 files changed

Lines changed: 20 additions & 4 deletions

File tree

Lib/test/test_deque.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,15 @@ def test_copy(self):
654654
self.assertNotEqual(id(d), id(e))
655655
self.assertEqual(list(d), list(e))
656656

657+
for i in range(5):
658+
for maxlen in range(-1, 6):
659+
s = [random.random() for j in range(i)]
660+
d = deque(s) if maxlen == -1 else deque(s, maxlen)
661+
e = d.copy()
662+
self.assertEqual(d, e)
663+
self.assertEqual(d.maxlen, e.maxlen)
664+
self.assertTrue(all(x is y for x, y in zip(d, e)))
665+
657666
def test_copy_method(self):
658667
mut = [10]
659668
d = deque([mut])

Modules/_collectionsmodule.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1211,27 +1211,34 @@ deque_traverse(dequeobject *deque, visitproc visit, void *arg)
12111211
static PyObject *
12121212
deque_copy(PyObject *deque)
12131213
{
1214+
dequeobject *old_deque = (dequeobject *)deque;
12141215
if (Py_TYPE(deque) == &deque_type) {
12151216
dequeobject *new_deque;
12161217
PyObject *rv;
12171218

12181219
new_deque = (dequeobject *)deque_new(&deque_type, (PyObject *)NULL, (PyObject *)NULL);
12191220
if (new_deque == NULL)
12201221
return NULL;
1221-
new_deque->maxlen = ((dequeobject *)deque)->maxlen;
1222-
rv = deque_extend(new_deque, deque);
1222+
new_deque->maxlen = old_deque->maxlen;
1223+
/* Fast path for the deque_repeat() common case where len(deque) == 1 */
1224+
if (Py_SIZE(deque) == 1 && new_deque->maxlen != 0) {
1225+
PyObject *item = old_deque->leftblock->data[old_deque->leftindex];
1226+
rv = deque_append(new_deque, item);
1227+
} else {
1228+
rv = deque_extend(new_deque, deque);
1229+
}
12231230
if (rv != NULL) {
12241231
Py_DECREF(rv);
12251232
return (PyObject *)new_deque;
12261233
}
12271234
Py_DECREF(new_deque);
12281235
return NULL;
12291236
}
1230-
if (((dequeobject *)deque)->maxlen == -1)
1237+
if (old_deque->maxlen == -1)
12311238
return PyObject_CallFunction((PyObject *)(Py_TYPE(deque)), "O", deque, NULL);
12321239
else
12331240
return PyObject_CallFunction((PyObject *)(Py_TYPE(deque)), "Oi",
1234-
deque, ((dequeobject *)deque)->maxlen, NULL);
1241+
deque, old_deque->maxlen, NULL);
12351242
}
12361243

12371244
PyDoc_STRVAR(copy_doc, "Return a shallow copy of a deque.");

0 commit comments

Comments
 (0)