diff -r 26e7d3935798 Python/ceval.c --- a/Python/ceval.c Sun Jan 13 16:04:05 2008 +0100 +++ b/Python/ceval.c Mon Jan 14 02:00:22 2008 +0100 @@ -2730,14 +2730,22 @@ PyEval_EvalCodeEx(PyCodeObject *co, PyOb PyString_AsString(co->co_name)); goto fail; } - /* XXX slow -- speed up using dictionary? */ + /* Speed hack: do raw pointer compares. As variables are normally + interned this should almost always hit. */ + for (j = 0; j < co->co_argcount; j++) { + PyObject *nm = PyTuple_GET_ITEM( + co->co_varnames, j); + if (nm == keyword) + goto kw_found; + } + /* Slow fallback, just in case */ for (j = 0; j < co->co_argcount; j++) { PyObject *nm = PyTuple_GET_ITEM( co->co_varnames, j); int cmp = PyObject_RichCompareBool( keyword, nm, Py_EQ); if (cmp > 0) - break; + goto kw_found; else if (cmp < 0) goto fail; } @@ -2754,20 +2762,20 @@ PyEval_EvalCodeEx(PyCodeObject *co, PyOb goto fail; } PyDict_SetItem(kwdict, keyword, value); - } - else { - if (GETLOCAL(j) != NULL) { - PyErr_Format(PyExc_TypeError, - "%.200s() got multiple " - "values for keyword " - "argument '%.400s'", - PyString_AsString(co->co_name), - PyString_AsString(keyword)); - goto fail; - } - Py_INCREF(value); - SETLOCAL(j, value); - } + continue; + } + kw_found: + if (GETLOCAL(j) != NULL) { + PyErr_Format(PyExc_TypeError, + "%.200s() got multiple " + "values for keyword " + "argument '%.400s'", + PyString_AsString(co->co_name), + PyString_AsString(keyword)); + goto fail; + } + Py_INCREF(value); + SETLOCAL(j, value); } if (argcount < co->co_argcount) { int m = co->co_argcount - defcount;