summaryrefslogtreecommitdiff
path: root/Modules/_collectionsmodule.c
diff options
context:
space:
mode:
authorRaymond Hettinger <python@rcn.com>2015-03-20 16:38:56 -0700
committerRaymond Hettinger <python@rcn.com>2015-03-20 16:38:56 -0700
commit39dadf7abf24302185f69493808dfb61fb8c4073 (patch)
tree758036c47e6d407d9c4bb973bde7344f45c2ce65 /Modules/_collectionsmodule.c
parent17d3a58e39c003ba4eecc5b4854a42b5d2546242 (diff)
downloadcpython-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.c34
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 */