Serhiy Storchaka added the comment:
Second version of the patch uses fast patch only when builtin __import__ is
not overridden. It is slightly slower (due to lookup of __import__).
>>> import timeit
>>> def f():
... import locale
...
>>> min(timeit.repeat(f, number=100000, repeat=10))
0.10502300000371179
The code is simpler, but still some cumbersome. It would be good to optimize
also "from locale import getlocale".
----------
Added file: http://bugs.python.org/file36816/faster_import_2.patch
_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue22557>
_______________________________________
diff -r 85de13b746ac Python/ceval.c
--- a/Python/ceval.c Sat Oct 04 16:09:02 2014 +0300
+++ b/Python/ceval.c Sun Oct 05 17:55:26 2014 +0300
@@ -2463,6 +2463,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int
TARGET(IMPORT_NAME) {
_Py_IDENTIFIER(__import__);
+ static PyObject *orig_func = NULL;
PyObject *name = GETITEM(names, oparg);
PyObject *func = _PyDict_GetItemId(f->f_builtins,
&PyId___import__);
PyObject *from, *level, *args, *res;
@@ -2474,6 +2475,29 @@ PyEval_EvalFrameEx(PyFrameObject *f, int
Py_INCREF(func);
from = POP();
level = TOP();
+ if (orig_func == NULL)
+ orig_func = _PyDict_GetItemId(
+ PyThreadState_GET()->interp->builtins_copy,
+ &PyId___import__);
+ if (func == orig_func && from == Py_None &&
+ PyLong_Check(level) && Py_SIZE(level) == 0 &&
+ PyUnicode_Check(name)) {
+ Py_ssize_t i = PyUnicode_FindChar(name, '.',
+ 0, PyUnicode_GET_LENGTH(name), 1);
+ if (i == -1) {
+ res = PyDict_GetItem(PyImport_GetModuleDict(), name);
+ if (res != NULL) {
+ Py_INCREF(res);
+ Py_DECREF(func);
+ Py_DECREF(level);
+ Py_DECREF(from);
+ SET_TOP(res);
+ DISPATCH();
+ }
+ }
+ else if (i == -2)
+ PyErr_Clear();
+ }
if (PyLong_AsLong(level) != -1 || PyErr_Occurred())
args = PyTuple_Pack(5,
name,
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com