diff options
| author | Raymond Hettinger <python@rcn.com> | 2015-03-20 16:38:56 -0700 |
|---|---|---|
| committer | Raymond Hettinger <python@rcn.com> | 2015-03-20 16:38:56 -0700 |
| commit | 39dadf7abf24302185f69493808dfb61fb8c4073 (patch) | |
| tree | 758036c47e6d407d9c4bb973bde7344f45c2ce65 /Modules/_collectionsmodule.c | |
| parent | 17d3a58e39c003ba4eecc5b4854a42b5d2546242 (diff) | |
| download | cpython-git-39dadf7abf24302185f69493808dfb61fb8c4073.tar.gz | |
Issue 23705: Improve the performance of __contains__ checks for deques.
Diffstat (limited to 'Modules/_collectionsmodule.c')
| -rw-r--r-- | Modules/_collectionsmodule.c | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c index d4794be08f..26a0c8ff6c 100644 --- a/Modules/_collectionsmodule.c +++ b/Modules/_collectionsmodule.c @@ -724,6 +724,38 @@ deque_count(dequeobject *deque, PyObject *v) PyDoc_STRVAR(count_doc, "D.count(value) -> integer -- return number of occurrences of value"); +static int +deque_contains(dequeobject *deque, PyObject *v) +{ + block *b = deque->leftblock; + Py_ssize_t index = deque->leftindex; + Py_ssize_t n = Py_SIZE(deque); + Py_ssize_t i; + size_t start_state = deque->state; + PyObject *item; + int cmp; + + for (i=0 ; i<n ; i++) { + CHECK_NOT_END(b); + item = b->data[index]; + cmp = PyObject_RichCompareBool(item, v, Py_EQ); + if (cmp) { + return cmp; + } + if (start_state != deque->state) { + PyErr_SetString(PyExc_RuntimeError, + "deque mutated during iteration"); + return -1; + } + index++; + if (index == BLOCKLEN) { + b = b->rightlink; + index = 0; + } + } + return 0; +} + static Py_ssize_t deque_len(dequeobject *deque) { @@ -1154,7 +1186,7 @@ static PySequenceMethods deque_as_sequence = { 0, /* sq_slice */ (ssizeobjargproc)deque_ass_item, /* sq_ass_item */ 0, /* sq_ass_slice */ - 0, /* sq_contains */ + (objobjproc)deque_contains, /* sq_contains */ (binaryfunc)deque_inplace_concat, /* sq_inplace_concat */ 0, /* sq_inplace_repeat */ |
