Python - производительность, кто разбирается в документации

Почему конструкция:

try:
    list.index(value)
    return True
except:
    return False

Работает быстрее, чем:

if value in list:

Суть вопроса в том, почему .index работает быстрее, чем in.

in перебирает список и выходит на первом совпадении, но index теоретически делает то же самое. Только вот тесты показали, что index быстрее, если нужно подтвердить или опровергнуть вхождение значения в список.


Ответы (1 шт):

Автор решения: gil9red

Нашел исходники методов и оказывается есть небольшая разница в их реализации, думаю в этом может быть причина

Реализация index:

static PyObject *
list_index_impl(PyListObject *self, PyObject *value, Py_ssize_t start,
                Py_ssize_t stop)
/*[clinic end generated code: output=ec51b88787e4e481 input=40ec5826303a0eb1]*/
{
    Py_ssize_t i;

    if (start < 0) {
        start += Py_SIZE(self);
        if (start < 0)
            start = 0;
    }
    if (stop < 0) {
        stop += Py_SIZE(self);
        if (stop < 0)
            stop = 0;
    }
    for (i = start; i < stop && i < Py_SIZE(self); i++) {
        PyObject *obj = self->ob_item[i];
        Py_INCREF(obj);
        int cmp = PyObject_RichCompareBool(obj, value, Py_EQ);
        Py_DECREF(obj);
        if (cmp > 0)
            return PyLong_FromSsize_t(i);
        else if (cmp < 0)
            return NULL;
    }
    PyErr_Format(PyExc_ValueError, "%R is not in list", value);
    return NULL;
}

Реализация in:

static int
list_contains(PyListObject *a, PyObject *el)
{
    PyObject *item;
    Py_ssize_t i;
    int cmp;

    for (i = 0, cmp = 0 ; cmp == 0 && i < Py_SIZE(a); ++i) {
        item = PyList_GET_ITEM(a, i);
        Py_INCREF(item);
        cmp = PyObject_RichCompareBool(item, el, Py_EQ);
        Py_DECREF(item);
    }
    return cmp;
}
→ Ссылка