]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Expose dict_contains() and PyDict_Contains() with is about 10% faster
authorRaymond Hettinger <python@rcn.com>
Tue, 25 Nov 2003 21:12:14 +0000 (21:12 +0000)
committerRaymond Hettinger <python@rcn.com>
Tue, 25 Nov 2003 21:12:14 +0000 (21:12 +0000)
than PySequence_Contains() and more clearly applicable to dicts.

Apply the new function in setobject.c where __contains__ checking is
ubiquitous.

Doc/api/concrete.tex
Include/dictobject.h
Misc/NEWS
Objects/dictobject.c
Objects/setobject.c

index bf8d4388e06870355883cb38973349fbf9794cb6..67852dbbd3cf2d5c64cd45bca3533ab09e6757ba 100644 (file)
@@ -1808,6 +1808,14 @@ format.
   Empties an existing dictionary of all key-value pairs.
 \end{cfuncdesc}
 
+\begin{cfuncdesc}{int}{PyDict_Contains}{PyObject *p, PyObject *key}
+  Determine if dictionary \var{p} contains \var{key}.  If an item
+  in \var{p} is matches \var{key}, return \code{1}, otherwise return
+  \code{0}.  On error, return \code{-1}.  This is equivalent to the
+  Python expression \samp{\var{key} in \var{p}}.
+  \versionadded{2.4}                    
+\end{cfuncdesc}
+
 \begin{cfuncdesc}{PyObject*}{PyDict_Copy}{PyObject *p}
   Returns a new dictionary that contains the same key-value pairs as
   \var{p}.
index c8ae912733f7b45f9e7f93f610b018c60b9cfaab..554b82e5a30f464d9c08c8943cf8c7da5570b055 100644 (file)
@@ -100,6 +100,7 @@ PyAPI_FUNC(PyObject *) PyDict_Values(PyObject *mp);
 PyAPI_FUNC(PyObject *) PyDict_Items(PyObject *mp);
 PyAPI_FUNC(int) PyDict_Size(PyObject *mp);
 PyAPI_FUNC(PyObject *) PyDict_Copy(PyObject *mp);
+PyAPI_FUNC(int) PyDict_Contains(PyObject *mp, PyObject *key);
 
 /* PyDict_Update(mp, other) is equivalent to PyDict_Merge(mp, other, 1). */
 PyAPI_FUNC(int) PyDict_Update(PyObject *mp, PyObject *other);
index f7b1e96710f7ed3cf4392153df7eca3e89298fc4..a3f3a18969ffafc9f2399a8cfd5418bc0e1a0ca9 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -231,6 +231,10 @@ Build
 C API
 -----
 
+- Added a new function, PyDict_Contains(d, k) which is like
+  PySequence_Contains() but is specific to dictionaries and executes
+  about 10% faster.
+
 - Added three new macros: Py_RETURN_NONE, Py_RETURN_TRUE, and Py_RETURN_FALSE.
   Each return the singleton they mention after Py_INCREF()ing them.
 
index 5d2240418fb7095826e36e70d5cc252a942b4f83..0cf71b53f6590b179b492681ff83c7611e6c6dc6 100644 (file)
@@ -1814,10 +1814,11 @@ static PyMethodDef mapp_methods[] = {
        {NULL,          NULL}   /* sentinel */
 };
 
-static int
-dict_contains(dictobject *mp, PyObject *key)
+int
+PyDict_Contains(PyObject *op, PyObject *key)
 {
        long hash;
+       dictobject *mp = (dictobject *)op;
 
        if (!PyString_CheckExact(key) ||
            (hash = ((PyStringObject *) key)->ob_shash) == -1) {
@@ -1837,7 +1838,7 @@ static PySequenceMethods dict_as_sequence = {
        0,                                      /* sq_slice */
        0,                                      /* sq_ass_item */
        0,                                      /* sq_ass_slice */
-       (objobjproc)dict_contains,              /* sq_contains */
+       (objobjproc)PyDict_Contains,            /* sq_contains */
        0,                                      /* sq_inplace_concat */
        0,                                      /* sq_inplace_repeat */
 };
index ce3f84eb69376011b685e5048e8d307334eb8219..c060077350e020d98fae6438fa1c4a66b6261a1d 100644 (file)
@@ -143,13 +143,13 @@ set_contains(PySetObject *so, PyObject *key)
        PyObject *tmp;
        int result;
 
-       result = PySequence_Contains(so->data, key);
+       result = PyDict_Contains(so->data, key);
        if (result == -1 && PyAnySet_Check(key)) {
                PyErr_Clear();
                tmp = frozenset_dict_wrapper(((PySetObject *)(key))->data);
                if (tmp == NULL)
                        return -1;
-               result = PySequence_Contains(so->data, tmp);
+               result = PyDict_Contains(so->data, tmp);
                Py_DECREF(tmp);
        }
        return result;
@@ -252,7 +252,7 @@ set_intersection(PySetObject *so, PyObject *other)
        }
 
        while ((item = PyIter_Next(it)) != NULL) {
-               if (PySequence_Contains(selfdata, item)) {
+               if (PyDict_Contains(selfdata, item)) {
                        if (PyDict_SetItem(tgtdata, item, Py_True) == -1) {
                                Py_DECREF(it);
                                Py_DECREF(result);
@@ -292,7 +292,7 @@ set_intersection_update(PySetObject *so, PyObject *other)
 
        selfdata = so->data;
        while ((item = PyIter_Next(it)) != NULL) {
-               if (PySequence_Contains(selfdata, item)) {
+               if (PyDict_Contains(selfdata, item)) {
                        if (PyDict_SetItem(newdict, item, Py_True) == -1) {
                                Py_DECREF(newdict);
                                Py_DECREF(it);
@@ -375,7 +375,7 @@ set_difference(PySetObject *so, PyObject *other)
        }
 
        while ((item = PyIter_Next(it)) != NULL) {
-               if (!PySequence_Contains(otherdata, item)) {
+               if (!PyDict_Contains(otherdata, item)) {
                        if (PyDict_SetItem(tgtdata, item, Py_True) == -1) {
                                Py_XDECREF(otherset);
                                Py_DECREF(it);
@@ -481,7 +481,7 @@ set_symmetric_difference_update(PySetObject *so, PyObject *other)
                return NULL;
 
        while ((item = PyIter_Next(it)) != NULL) {
-               if (PySequence_Contains(selfdata, item)) {
+               if (PyDict_Contains(selfdata, item)) {
                        if (PyDict_DelItem(selfdata, item) == -1) {
                                Py_XDECREF(otherset);
                                Py_DECREF(it);
@@ -541,7 +541,7 @@ set_symmetric_difference(PySetObject *so, PyObject *other)
                return NULL;
        }
        while ((item = PyIter_Next(it)) != NULL) {
-               if (!PySequence_Contains(selfdata, item)) {
+               if (!PyDict_Contains(selfdata, item)) {
                        if (PyDict_SetItem(tgtdata, item, Py_True) == -1) {
                                Py_DECREF(it);
                                Py_DECREF(item);
@@ -562,7 +562,7 @@ set_symmetric_difference(PySetObject *so, PyObject *other)
                return NULL;
        }
        while ((item = PyIter_Next(it)) != NULL) {
-               if (!PySequence_Contains(otherdata, item)) {
+               if (!PyDict_Contains(otherdata, item)) {
                        if (PyDict_SetItem(tgtdata, item, Py_True) == -1) {
                                Py_DECREF(it);
                                Py_DECREF(item);
@@ -634,7 +634,7 @@ set_issubset(PySetObject *so, PyObject *other)
 
        otherdata = ((PySetObject *)other)->data;
        while ((item = PyIter_Next(it)) != NULL) {
-               if (!PySequence_Contains(otherdata, item)) {
+               if (!PyDict_Contains(otherdata, item)) {
                        Py_DECREF(it);
                        Py_DECREF(item);
                        Py_RETURN_FALSE;