Commit 133138a2 authored by Serhiy Storchaka's avatar Serhiy Storchaka

Issue #22557: Now importing already imported modules is up to 2.5 times faster.

parent cde03fa0
......@@ -41,6 +41,7 @@ typedef struct _is {
#endif
PyObject *builtins_copy;
PyObject *import_func;
} PyInterpreterState;
#endif
......
......@@ -10,6 +10,8 @@ What's New in Python 3.6.0 alpha 4
Core and Builtins
-----------------
- Issue #22557: Now importing already imported modules is up to 2.5 times faster.
- Issue #17596: Include <wincrypt.h> to help with Min GW building.
- Issue #27507: Add integer overflow check in bytearray.extend(). Patch by
......
......@@ -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;
......@@ -5158,6 +5137,50 @@ cmp_outcome(int op, PyObject *v, PyObject *w)
return v;
}
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)
{
......
This diff is collapsed.
......@@ -254,6 +254,11 @@ import_init(PyInterpreterState *interp, PyObject *sysmod)
interp->importlib = importlib;
Py_INCREF(interp->importlib);
interp->import_func = PyDict_GetItemString(interp->builtins, "__import__");
if (interp->import_func == NULL)
Py_FatalError("Py_Initialize: __import__ not found");
Py_INCREF(interp->import_func);
/* Import the _imp module */
impmod = PyInit_imp();
if (impmod == NULL) {
......
......@@ -90,6 +90,7 @@ PyInterpreterState_New(void)
interp->codecs_initialized = 0;
interp->fscodec_initialized = 0;
interp->importlib = NULL;
interp->import_func = NULL;
#ifdef HAVE_DLOPEN
#if HAVE_DECL_RTLD_NOW
interp->dlopenflags = RTLD_NOW;
......@@ -128,6 +129,7 @@ PyInterpreterState_Clear(PyInterpreterState *interp)
Py_CLEAR(interp->builtins);
Py_CLEAR(interp->builtins_copy);
Py_CLEAR(interp->importlib);
Py_CLEAR(interp->import_func);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment