bpo-31415: Add -X importtime option (GH-3490)

It shows show import time of each module.
It's useful for optimizing startup time.

Typical usage: python -X importtime -c 'import requests'
This commit is contained in:
INADA Naoki 2017-10-03 19:46:34 +09:00 committed by GitHub
parent e8c368df22
commit 1a87de7fcf
3 changed files with 51 additions and 0 deletions

View file

@ -1667,8 +1667,38 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
}
}
else {
static int ximporttime = 0;
static int import_level;
static _PyTime_t accumulated;
_Py_IDENTIFIER(importtime);
_PyTime_t t1 = 0, accumulated_copy = accumulated;
Py_XDECREF(mod);
/* XOptions is initialized after first some imports.
* So we can't have negative cache.
* Anyway, importlib.__find_and_load is much slower than
* _PyDict_GetItemId()
*/
if (ximporttime == 0) {
PyObject *xoptions = PySys_GetXOptions();
if (xoptions) {
PyObject *value = _PyDict_GetItemId(xoptions, &PyId_importtime);
ximporttime = (value == Py_True);
}
if (ximporttime) {
fputs("import time: self [us] | cumulative | imported package\n",
stderr);
}
}
if (ximporttime) {
import_level++;
t1 = _PyTime_GetMonotonicClock();
accumulated = 0;
}
if (PyDTrace_IMPORT_FIND_LOAD_START_ENABLED())
PyDTrace_IMPORT_FIND_LOAD_START(PyUnicode_AsUTF8(abs_name));
@ -1680,6 +1710,18 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
PyDTrace_IMPORT_FIND_LOAD_DONE(PyUnicode_AsUTF8(abs_name),
mod != NULL);
if (ximporttime) {
_PyTime_t cum = _PyTime_GetMonotonicClock() - t1;
import_level--;
fprintf(stderr, "import time: %9ld | %10ld | %*s%s\n",
(long)_PyTime_AsMicroseconds(cum - accumulated, _PyTime_ROUND_CEILING),
(long)_PyTime_AsMicroseconds(cum, _PyTime_ROUND_CEILING),
import_level*2, "", PyUnicode_AsUTF8(abs_name));
accumulated = accumulated_copy + cum;
}
if (mod == NULL) {
goto error;
}