Serhiy Storchaka added the comment:
I'm not experienced in import machinery. Here is preliminary patch which
implements my idea for particular case.
Performance effect is almost so good as manual caching in a global.
>>> import timeit
>>> def f():
... import locale
...
>>> min(timeit.repeat(f, number=100000, repeat=10))
0.09563599999819417
Of course it breaks tests.
> It's possible there is room for other optimisations that don't break the
> import override semantics (such as a fast path for when __import__ is the
> standard import function).
Good idea.
----------
keywords: +patch
Added file: http://bugs.python.org/file36814/faster_import.patch
_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue22557>
_______________________________________
diff -r 85de13b746ac Lib/test/test_import.py
--- a/Lib/test/test_import.py Sat Oct 04 16:09:02 2014 +0300
+++ b/Lib/test/test_import.py Sun Oct 05 17:15:42 2014 +0300
@@ -312,7 +312,7 @@ class ImportTests(unittest.TestCase):
@cpython_only
def test_delete_builtins_import(self):
- args = ["-c", "del __builtins__.__import__; import os"]
+ args = ["-c", "del __builtins__.__import__; import this"]
popen = script_helper.spawn_python(*args)
stdout, stderr = popen.communicate()
self.assertIn(b"ImportError", stdout)
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:15:42 2014 +0300
@@ -2464,16 +2464,42 @@ PyEval_EvalFrameEx(PyFrameObject *f, int
TARGET(IMPORT_NAME) {
_Py_IDENTIFIER(__import__);
PyObject *name = GETITEM(names, oparg);
- PyObject *func = _PyDict_GetItemId(f->f_builtins,
&PyId___import__);
+ PyObject *func;
PyObject *from, *level, *args, *res;
+ from = POP();
+ level = TOP();
+ if (from == Py_None && PyUnicode_Check(name)) {
+ if (PyLong_AsLong(level) == 0) {
+ 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(level);
+ Py_DECREF(from);
+ SET_TOP(res);
+ DISPATCH();
+ }
+ }
+ else if (i == -2) {
+ Py_DECREF(level);
+ Py_DECREF(from);
+ STACKADJ(-1);
+ goto error;
+ }
+ }
+ else if (PyErr_Occurred())
+ PyErr_Clear();
+ }
+ func = _PyDict_GetItemId(f->f_builtins, &PyId___import__);
if (func == NULL) {
PyErr_SetString(PyExc_ImportError,
"__import__ not found");
+ STACKADJ(-1);
goto error;
}
Py_INCREF(func);
- from = POP();
- level = TOP();
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