@@ -1667,8 +1667,38 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
16671667 }
16681668 }
16691669 else {
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+
16701677 Py_XDECREF (mod );
16711678
1679+ /* 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+
16721702 if (PyDTrace_IMPORT_FIND_LOAD_START_ENABLED ())
16731703 PyDTrace_IMPORT_FIND_LOAD_START (PyUnicode_AsUTF8 (abs_name ));
16741704
@@ -1680,6 +1710,18 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
16801710 PyDTrace_IMPORT_FIND_LOAD_DONE (PyUnicode_AsUTF8 (abs_name ),
16811711 mod != NULL );
16821712
1713+ 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+
16831725 if (mod == NULL ) {
16841726 goto error ;
16851727 }
0 commit comments