配置Python导入时间

时间:2016-01-12 23:27:45

标签: python profiling python-import

有没有办法找出Python中使用时间最长的导入?查看python -m cProfile <script>的输出,它似乎不包含import语句(可以理解为可能存在巨大的依赖树)。最初我认为这是因为我看到__import__()次调用的行,但我认为这实际上可能是因为代码某处明确地调用它,只有import语句的玩具程序没有一行它

现在我正在使用:

start = time.time()
import <module>
print '%s / time: %f' % (<module>, time.time()-start)

围绕每个模块,但它不会递归地对其进行分析,以查看导入中的哪个导入可能会使时间膨胀。

3 个答案:

答案 0 :(得分:1)

正如danielu13的评论中所述,您真正想要分析的是导入此模块时在模块内执行的代码。

似乎cProfile包含在其输出中导入时执行的代码。对于模块级代码,它显示为<module>。 许多软件包都作为__init__.py文件导入,因此gprof2dot显示__init__:23:<module>(行号可能不同),但不会告诉您文件来自哪个软件包。

使用cprofilev,您可以找出哪些文件(以及包)占用大部分时间。

一个侧注:在某些情况下,分析导入实际上是有意义的。在我的系统上,导入模块networkx(https://networkx.github.io/)需要1.7秒。

答案 1 :(得分:0)

这是一个完全合法的问题。例如,尝试加速CLI应用程序的冷启动是有意义的。 Python 3.7现在提供了一个打印导入时间的选项:https://docs.python.org/3/using/cmdline.html#envvar-PYTHONPROFILEIMPORTTIME

您可以运行:

python -X importttime myscript.py

或:

PYTHONPROFILEIMPORTTIME=1 myscript.py

答案 2 :(得分:0)

Python 2.7的一种非常简单且非分层的解决方案,它打印自上一个模块以来的模块名称和导入时间:

LAST_TIME = time.time()

class ImportHook(object):
    def find_module(self, fullname, path=None):
        global LAST_TIME
        cur_time = time.time()
        delta = cur_time - LAST_TIME
        long_time = '!!!!!!!!!!!!!!\n' * 10 if delta > 0.05 else ''
        print '%0.3f %s \n %s' % (delta, long_time, fullname),
        LAST_TIME = cur_time

import sys
sys.meta_path.insert(0, ImportHook())