aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Python/getargs.c
diff options
context:
space:
mode:
authorSebastian Berg <sebastian@sipsolutions.net>2019-12-18 00:51:22 -0600
committerInada Naoki <songofacandy@gmail.com>2019-12-18 15:51:22 +0900
commit75bb07e92baa7267a61056d03d7e6b475588e793 (patch)
treecb121c8bd4a5cf925359bdf4d1d591ec34528ae2 /Python/getargs.c
parent50d4f12958bf806a4e1a1021d70cfd5d448c5cba (diff)
downloadcpython-75bb07e92baa7267a61056d03d7e6b475588e793.tar.gz
cpython-75bb07e92baa7267a61056d03d7e6b475588e793.zip
bpo-39028: Performance enhancement in keyword extraction (GH-17576)
All keywords should first be checked for pointer identity. Only after that failed for all keywords (unlikely) should unicode equality be used. The original code would call unicode equality on any non-matching keyword argument. Meaning calling it often e.g. when a function has many kwargs but only the last one is provided.
Diffstat (limited to 'Python/getargs.c')
-rw-r--r--Python/getargs.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/Python/getargs.c b/Python/getargs.c
index 351889f8e51..d5caf47a028 100644
--- a/Python/getargs.c
+++ b/Python/getargs.c
@@ -2053,14 +2053,18 @@ find_keyword(PyObject *kwnames, PyObject *const *kwstack, PyObject *key)
Py_ssize_t i, nkwargs;
nkwargs = PyTuple_GET_SIZE(kwnames);
- for (i=0; i < nkwargs; i++) {
+ for (i = 0; i < nkwargs; i++) {
PyObject *kwname = PyTuple_GET_ITEM(kwnames, i);
- /* ptr==ptr should match in most cases since keyword keys
- should be interned strings */
+ /* kwname == key will normally find a match in since keyword keys
+ should be interned strings; if not retry below in a new loop. */
if (kwname == key) {
return kwstack[i];
}
+ }
+
+ for (i = 0; i < nkwargs; i++) {
+ PyObject *kwname = PyTuple_GET_ITEM(kwnames, i);
assert(PyUnicode_Check(kwname));
if (_PyUnicode_EQ(kwname, key)) {
return kwstack[i];