Python中导入所花费的时间

时间:2009-04-20 11:29:47

标签: python import

我想知道导入对内置模块和用户定义模块需要多长时间。

8 个答案:

答案 0 :(得分:6)

配置导入的一种方法是使用bzr source code中使用的profile_imports模块:

# put those two lines at the top of your script
import profile_imports
profile_imports.install()

# display the results
profile_imports.log_stack_info(sys.stderr)

除了给你进口的时间外,这也估计了编制正则表达式的时间,这通常是进口放缓的重要原因。

答案 1 :(得分:5)

你可以测试这个运行

$ time python -c "import math"

然而,这会对你有什么帮助?进口只发生一次,几乎永远不会成为瓶颈。反复导入同一个模块的速度不会比导入一次慢得多,因为Python会跟踪哪些模块已被导入。

你到底想要实现什么目标?

答案 2 :(得分:3)

要了解导入需要多长时间,最简单的方法可能是使用timeit module ..

>>> import timeit
>>> t = timeit.Timer('import urllib')
>>> t.timeit(number = 1000000)
0.98621106147766113

因此要导入urllib 100万次,花了不到一秒钟(在Macbook Pro上)..

  

我有一个导入其他模块的主脚本。我需要计算需要多少时间

如果您的意思是脚本执行总时间,在Linux / OS X / Cygwin上,您可以使用time命令运行脚本,例如:

$ time python myscript.py 

real    0m0.046s
user    0m0.024s
sys     0m0.020s

(请记住,包括所有Python解释器的启动时间,以及实际的代码执行时间,尽管它的数量非常微不足道)

另一种可能更有用的方法是分析脚本:

而不是使用

运行代码
$ python myscript.py 

..你用..

$ python -m cProfile myscript.py
         1059 function calls in 0.015 CPU seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    0.000    0.000 <string>:1(<module>)
        1    0.002    0.002    0.015    0.015 myscript.py:1(<module>)
   [...]

我没有发现命令行输出非常容易阅读,因此我几乎总是使用gprof2dot,它将分析信息转换为漂亮的graphviz图:

$ python -m cProfile -o myscript.prof myscript.py
$ python gprof2dot.py -o myscript.dot -f pstats myscript.prof
$ dot -Tpng -o profile.png prof_runtest.dot -Gbgcolor=black

Example output (1429x1896px PNG)

答案 3 :(得分:3)

从Python3.7版本开始,新的-X importtime选项可用。 要衡量导入时间,只需使用该选项简单地执行脚本,例如python -X importtime my_script.py

供参考:

答案 4 :(得分:1)

使用cProfile:

python -m cProfile yourscript.py

答案 5 :(得分:0)

在Python 2.4中测试Windows - 您可以自己尝试。

>>> import time

>>> ## Built-in module
>>> def testTime():
        now = time.clock() # use time.time() on unix-based systems
        import math
        print time.clock() - now

>>> testTime()
7.54285810167e-006



>>> ## My own module
>>> def testTime():
        now = time.clock()
        import myBuiltInModule # Not its actual name ;-)
        print time.clock() - now

>>> testTime()
0.00253174635324
>>> testTime()
3.70158777141e-006

因此,缓存模块与从头开始引入的模块之间存在很大差异。为了说明,我们可以重新加载模块:

>>> def testTime():
        now = time.clock()
        reload(myBuiltInModule )
        print time.clock() - now


>>> testTime()
0.00250017809526

答案 6 :(得分:0)

我遇到了这个问题,分析了一个具有多秒启动时间的大型遗留应用程序。将内置导入器替换为执行某些分析的内容相对简单。下面是一个显示每个模块执行大约需要多长时间的hacky方式:

import os
import sys
import time


class ImportEventNode(object):
    def __init__(self, name, start_time, children=None, end_time=None):
        self.name = name
        self.start_time = start_time
        self.children = [] if children is None else children
        self.end_time = end_time

    def __repr__(self):
        return 'ImportEventNode({self.name}, {self.start_time}, children={self.children}, end_time={self.end_time})'.format(self=self)

    @property
    def total_time(self):
        return self.end_time - self.start_time

    @property
    def net_time(self):
        return self.total_time - sum(child.total_time for child in self.children)


root_node = cur_node = None

all_nodes = []
old_import = __import__
def __import__(*args, **kwargs):
    global root_node, cur_node
    name = args[0]
    if name not in sys.modules:
        t0 = time.time()
        if root_node is None:
            root_node = prev_node = cur_node = lcur_node = ImportEventNode(args[0], t0)
        else:
            prev_node = cur_node
            cur_node = lcur_node = ImportEventNode(name, t0)
            prev_node.children.append(cur_node)
        try:
            ret = old_import(*args, **kwargs)
        finally:
            lcur_node.end_time = time.time()
        all_nodes.append(lcur_node)
        cur_node = prev_node
        return ret
    else:
        return old_import(*args, **kwargs)


__builtins__.__import__ = __import__

运行一个简单的例子,这是它在导入scipy.stats时的样子:

:import scipy.stats
:
:nodes = sorted(all_nodes, key=(lambda x: x.net_time), reverse=True)
:for node in nodes[:10]:
:    print(node.name, node.net_time)
:
:<EOF>
('pkg_resources', 0.08431100845336914)
('', 0.05861020088195801)
('decomp_schur', 0.016885995864868164)
('PIL', 0.0143890380859375)
('scipy.stats', 0.010602712631225586)
('pkg_resources._vendor.packaging.specifiers', 0.007072925567626953)
('add_newdocs', 0.00637507438659668)
('mtrand', 0.005497932434082031)
('scipy.sparse.linalg', 0.005171060562133789)
('scipy.linalg', 0.004471778869628906)

答案 7 :(得分:0)

这是对szymonskjern结合Python Profilerstuna的建议的扩展。

首先安装金枪鱼

pip install tuna

然后,创建一个python扩展文件并将其命名为您想要的任何名称。此处我们将其命名为 timit_package.py

在这个文件中,包括内置和用户定义的模块。

这里,我只测试

import mne

然后,在终端

python -mcProfile -o program.prof timit_package.py

等待几秒钟,然后将以下行粘贴到终端中

tuna program.prof

将生成浏览器和配置文件。

enter image description here

我正在用 python 3.9 测试这个