[Python-checkins] bpo-39028: Performance enhancement in keyword extraction (GH-17576)

Inada Naoki webhook-mailer at python.org
Wed Dec 18 01:51:49 EST 2019


https://github.com/python/cpython/commit/75bb07e92baa7267a61056d03d7e6b475588e793
commit: 75bb07e92baa7267a61056d03d7e6b475588e793
branch: master
author: Sebastian Berg <sebastian at sipsolutions.net>
committer: Inada Naoki <songofacandy at gmail.com>
date: 2019-12-18T15:51:22+09:00
summary:

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.

files:
A Misc/NEWS.d/next/Core and Builtins/2019-12-17-23-20-51.bpo-39028.SND4TB.rst
M Python/getargs.c

diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-12-17-23-20-51.bpo-39028.SND4TB.rst b/Misc/NEWS.d/next/Core and Builtins/2019-12-17-23-20-51.bpo-39028.SND4TB.rst
new file mode 100644
index 0000000000000..ee7639ead9dd9
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2019-12-17-23-20-51.bpo-39028.SND4TB.rst	
@@ -0,0 +1 @@
+Slightly improve the speed of keyword argument parsing with many kwargs by strengthening the assumption that kwargs are interned strings.
\ No newline at end of file
diff --git a/Python/getargs.c b/Python/getargs.c
index 351889f8e5189..d5caf47a02838 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];



More information about the Python-checkins mailing list