bpo-31415: Add `-X importtime` option (GH-3490) · python/cpython@1a87de7
@@ -1667,8 +1667,38 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
16671667 }
16681668 }
16691669else {
1670+static int ximporttime = 0;
1671+static int import_level;
1672+static _PyTime_t accumulated;
1673+_Py_IDENTIFIER(importtime);
1674+1675+_PyTime_t t1 = 0, accumulated_copy = accumulated;
1676+16701677Py_XDECREF(mod);
167116781679+/* XOptions is initialized after first some imports.
1680+ * So we can't have negative cache.
1681+ * Anyway, importlib.__find_and_load is much slower than
1682+ * _PyDict_GetItemId()
1683+ */
1684+if (ximporttime == 0) {
1685+PyObject *xoptions = PySys_GetXOptions();
1686+if (xoptions) {
1687+PyObject *value = _PyDict_GetItemId(xoptions, &PyId_importtime);
1688+ximporttime = (value == Py_True);
1689+ }
1690+if (ximporttime) {
1691+fputs("import time: self [us] | cumulative | imported package\n",
1692+stderr);
1693+ }
1694+ }
1695+1696+if (ximporttime) {
1697+import_level++;
1698+t1 = _PyTime_GetMonotonicClock();
1699+accumulated = 0;
1700+ }
1701+16721702if (PyDTrace_IMPORT_FIND_LOAD_START_ENABLED())
16731703PyDTrace_IMPORT_FIND_LOAD_START(PyUnicode_AsUTF8(abs_name));
16741704@@ -1680,6 +1710,18 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
16801710PyDTrace_IMPORT_FIND_LOAD_DONE(PyUnicode_AsUTF8(abs_name),
16811711mod != NULL);
168217121713+if (ximporttime) {
1714+_PyTime_t cum = _PyTime_GetMonotonicClock() - t1;
1715+1716+import_level--;
1717+fprintf(stderr, "import time: %9ld | %10ld | %*s%s\n",
1718+ (long)_PyTime_AsMicroseconds(cum - accumulated, _PyTime_ROUND_CEILING),
1719+ (long)_PyTime_AsMicroseconds(cum, _PyTime_ROUND_CEILING),
1720+import_level*2, "", PyUnicode_AsUTF8(abs_name));
1721+1722+accumulated = accumulated_copy + cum;
1723+ }
1724+16831725if (mod == NULL) {
16841726 goto error;
16851727 }