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

This commit is contained in:
Raymond Hettinger 2018-10-08 08:02:41 -07:00 committed by GitHub
parent fc8205cb4b
commit de2e448414
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 40 additions and 15 deletions

View File

@ -0,0 +1 @@
25% speedup in argument parsing for the functions in the bisect module.

View File

@ -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)
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)
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\
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)
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)
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;