summaryrefslogtreecommitdiffstats
path: root/Python/ceval.c
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2016-08-02 19:51:21 (GMT)
committerSerhiy Storchaka <storchaka@gmail.com>2016-08-02 19:51:21 (GMT)
commit133138a284be1985ebd9ec9014f1306b9a425d98 (patch)
tree15d5ad35ad76c65f88cb739100ff152194e96ef8 /Python/ceval.c
parentcde03fa0381fcb7f7d3ba0dff4e784eade1f3031 (diff)
downloadcpython-133138a284be1985ebd9ec9014f1306b9a425d98.zip
cpython-133138a284be1985ebd9ec9014f1306b9a425d98.tar.gz
cpython-133138a284be1985ebd9ec9014f1306b9a425d98.tar.bz2
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.c79
1 files changed, 51 insertions, 28 deletions
diff --git a/Python/ceval.c b/Python/ceval.c
index 7c664ad..7ca3ad2 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;