diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2016-08-02 22:51:21 +0300 |
---|---|---|
committer | Serhiy Storchaka <storchaka@gmail.com> | 2016-08-02 22:51:21 +0300 |
commit | 133138a284be1985ebd9ec9014f1306b9a425d98 (patch) | |
tree | 15d5ad35ad76c65f88cb739100ff152194e96ef8 /Python/ceval.c | |
parent | cde03fa0381fcb7f7d3ba0dff4e784eade1f3031 (diff) | |
download | cpython-git-133138a284be1985ebd9ec9014f1306b9a425d98.tar.gz |
Issue #22557: Now importing already imported modules is up to 2.5 times faster.
Diffstat (limited to 'Python/ceval.c')
-rw-r--r-- | Python/ceval.c | 79 |
1 files changed, 51 insertions, 28 deletions
diff --git a/Python/ceval.c b/Python/ceval.c index 7c664ad6c6..7ca3ad253f 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -139,6 +139,7 @@ static int maybe_call_line_trace(Py_tracefunc, PyObject *, PyThreadState *, PyFrameObject *, int *, int *, int *); static PyObject * cmp_outcome(int, PyObject *, PyObject *); +static PyObject * import_name(PyFrameObject *, PyObject *, PyObject *, PyObject *); static PyObject * import_from(PyObject *, PyObject *); static int import_all_from(PyObject *, PyObject *); static void format_exc_check_arg(PyObject *, const char *, PyObject *); @@ -2808,37 +2809,15 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) } TARGET(IMPORT_NAME) { - _Py_IDENTIFIER(__import__); PyObject *name = GETITEM(names, oparg); - PyObject *func = _PyDict_GetItemId(f->f_builtins, &PyId___import__); - PyObject *from, *level, *args, *res; - if (func == NULL) { - PyErr_SetString(PyExc_ImportError, - "__import__ not found"); - goto error; - } - Py_INCREF(func); - from = POP(); - level = TOP(); - args = PyTuple_Pack(5, - name, - f->f_globals, - f->f_locals == NULL ? - Py_None : f->f_locals, - from, - level); - Py_DECREF(level); - Py_DECREF(from); - if (args == NULL) { - Py_DECREF(func); - STACKADJ(-1); - goto error; - } + PyObject *fromlist = POP(); + PyObject *level = TOP(); + PyObject *res; READ_TIMESTAMP(intr0); - res = PyEval_CallObject(func, args); + res = import_name(f, name, fromlist, level); + Py_DECREF(level); + Py_DECREF(fromlist); READ_TIMESTAMP(intr1); - Py_DECREF(args); - Py_DECREF(func); SET_TOP(res); if (res == NULL) goto error; @@ -5159,6 +5138,50 @@ cmp_outcome(int op, PyObject *v, PyObject *w) } static PyObject * +import_name(PyFrameObject *f, PyObject *name, PyObject *fromlist, PyObject *level) +{ + _Py_IDENTIFIER(__import__); + PyObject *import_func, *args, *res; + + import_func = _PyDict_GetItemId(f->f_builtins, &PyId___import__); + if (import_func == NULL) { + PyErr_SetString(PyExc_ImportError, "__import__ not found"); + return NULL; + } + + /* Fast path for not overloaded __import__. */ + if (import_func == PyThreadState_GET()->interp->import_func) { + int ilevel = _PyLong_AsInt(level); + if (ilevel == -1 && PyErr_Occurred()) { + return NULL; + } + res = PyImport_ImportModuleLevelObject( + name, + f->f_globals, + f->f_locals == NULL ? Py_None : f->f_locals, + fromlist, + ilevel); + return res; + } + + Py_INCREF(import_func); + args = PyTuple_Pack(5, + name, + f->f_globals, + f->f_locals == NULL ? Py_None : f->f_locals, + fromlist, + level); + if (args == NULL) { + Py_DECREF(import_func); + return NULL; + } + res = PyEval_CallObject(import_func, args); + Py_DECREF(args); + Py_DECREF(import_func); + return res; +} + +static PyObject * import_from(PyObject *v, PyObject *name) { PyObject *x; |