Commit de2e4484 authored by Raymond Hettinger's avatar Raymond Hettinger Committed by GitHub

bpo-34925: Optimize common case for bisect() argument parsing (#9753)

parent fc8205cb
25% speedup in argument parsing for the functions in the bisect module.
...@@ -8,7 +8,7 @@ Converted to C by Dmitry Vasiliev (dima at hlabs.spb.ru). ...@@ -8,7 +8,7 @@ Converted to C by Dmitry Vasiliev (dima at hlabs.spb.ru).
_Py_IDENTIFIER(insert); _Py_IDENTIFIER(insert);
static Py_ssize_t static inline Py_ssize_t
internal_bisect_right(PyObject *list, PyObject *item, Py_ssize_t lo, Py_ssize_t hi) internal_bisect_right(PyObject *list, PyObject *item, Py_ssize_t lo, Py_ssize_t hi)
{ {
PyObject *litem; PyObject *litem;
...@@ -53,9 +53,15 @@ bisect_right(PyObject *self, PyObject *args, PyObject *kw) ...@@ -53,9 +53,15 @@ bisect_right(PyObject *self, PyObject *args, PyObject *kw)
Py_ssize_t index; Py_ssize_t index;
static char *keywords[] = {"a", "x", "lo", "hi", NULL}; static char *keywords[] = {"a", "x", "lo", "hi", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|nn:bisect_right", if (kw == NULL && PyTuple_GET_SIZE(args) == 2) {
keywords, &list, &item, &lo, &hi)) list = PyTuple_GET_ITEM(args, 0);
return NULL; item = PyTuple_GET_ITEM(args, 1);
}
else {
if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|nn:bisect_right",
keywords, &list, &item, &lo, &hi))
return NULL;
}
index = internal_bisect_right(list, item, lo, hi); index = internal_bisect_right(list, item, lo, hi);
if (index < 0) if (index < 0)
return NULL; return NULL;
...@@ -83,16 +89,23 @@ insort_right(PyObject *self, PyObject *args, PyObject *kw) ...@@ -83,16 +89,23 @@ insort_right(PyObject *self, PyObject *args, PyObject *kw)
Py_ssize_t index; Py_ssize_t index;
static char *keywords[] = {"a", "x", "lo", "hi", NULL}; static char *keywords[] = {"a", "x", "lo", "hi", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|nn:insort_right", if (kw == NULL && PyTuple_GET_SIZE(args) == 2) {
keywords, &list, &item, &lo, &hi)) list = PyTuple_GET_ITEM(args, 0);
return NULL; item = PyTuple_GET_ITEM(args, 1);
}
else {
if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|nn:insort_right",
keywords, &list, &item, &lo, &hi))
return NULL;
}
index = internal_bisect_right(list, item, lo, hi); index = internal_bisect_right(list, item, lo, hi);
if (index < 0) if (index < 0)
return NULL; return NULL;
if (PyList_CheckExact(list)) { if (PyList_CheckExact(list)) {
if (PyList_Insert(list, index, item) < 0) if (PyList_Insert(list, index, item) < 0)
return NULL; return NULL;
} else { }
else {
result = _PyObject_CallMethodId(list, &PyId_insert, "nO", index, item); result = _PyObject_CallMethodId(list, &PyId_insert, "nO", index, item);
if (result == NULL) if (result == NULL)
return NULL; return NULL;
...@@ -112,7 +125,7 @@ If x is already in a, insert it to the right of the rightmost x.\n\ ...@@ -112,7 +125,7 @@ If x is already in a, insert it to the right of the rightmost x.\n\
Optional args lo (default 0) and hi (default len(a)) bound the\n\ Optional args lo (default 0) and hi (default len(a)) bound the\n\
slice of a to be searched.\n"); slice of a to be searched.\n");
static Py_ssize_t static inline Py_ssize_t
internal_bisect_left(PyObject *list, PyObject *item, Py_ssize_t lo, Py_ssize_t hi) internal_bisect_left(PyObject *list, PyObject *item, Py_ssize_t lo, Py_ssize_t hi)
{ {
PyObject *litem; PyObject *litem;
...@@ -157,9 +170,15 @@ bisect_left(PyObject *self, PyObject *args, PyObject *kw) ...@@ -157,9 +170,15 @@ bisect_left(PyObject *self, PyObject *args, PyObject *kw)
Py_ssize_t index; Py_ssize_t index;
static char *keywords[] = {"a", "x", "lo", "hi", NULL}; static char *keywords[] = {"a", "x", "lo", "hi", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|nn:bisect_left", if (kw == NULL && PyTuple_GET_SIZE(args) == 2) {
keywords, &list, &item, &lo, &hi)) list = PyTuple_GET_ITEM(args, 0);
return NULL; item = PyTuple_GET_ITEM(args, 1);
}
else {
if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|nn:bisect_left",
keywords, &list, &item, &lo, &hi))
return NULL;
}
index = internal_bisect_left(list, item, lo, hi); index = internal_bisect_left(list, item, lo, hi);
if (index < 0) if (index < 0)
return NULL; return NULL;
...@@ -187,9 +206,14 @@ insort_left(PyObject *self, PyObject *args, PyObject *kw) ...@@ -187,9 +206,14 @@ insort_left(PyObject *self, PyObject *args, PyObject *kw)
Py_ssize_t index; Py_ssize_t index;
static char *keywords[] = {"a", "x", "lo", "hi", NULL}; static char *keywords[] = {"a", "x", "lo", "hi", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|nn:insort_left", if (kw == NULL && PyTuple_GET_SIZE(args) == 2) {
keywords, &list, &item, &lo, &hi)) list = PyTuple_GET_ITEM(args, 0);
return NULL; item = PyTuple_GET_ITEM(args, 1);
} else {
if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|nn:insort_left",
keywords, &list, &item, &lo, &hi))
return NULL;
}
index = internal_bisect_left(list, item, lo, hi); index = internal_bisect_left(list, item, lo, hi);
if (index < 0) if (index < 0)
return NULL; return NULL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment