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

Reply via email to