2009-04-20 3 views
9

Я хочу знать, сколько времени занимает импорт как для встроенных, так и для пользовательских модулей.Время, затраченное на импорт в Python

+0

Она меняется. Укажите конкретный сценарий или ситуацию. –

+0

-1: В ответ были добавлены дополнительные факты. В вопрос нужно поставить новые факты, а не ответы. –

ответ

5

Вы можете проверить это стереосистеме и обновите

$ time python -c "import math" 

Однако, что бы это поможет? Импорт происходит только один раз и почти никогда не будет бутылочной шее. Импорт одного и того же модуля снова и снова будет выполняться значительно медленнее, чем импортировать его один раз, поскольку Python отслеживает, какие модули уже были импортированы.

Что вы на самом деле пытаетесь достичь?

+0

У меня есть мастер-скрипт, который импортирует другие модули. Мне нужно рассчитать, сколько времени потребуется – user46646

+0

@rejinacm: Пожалуйста, обновите свой вопрос новыми фактами. –

1

Использование Cprofile:

python -m cProfile yourscript.py 
+0

Я использую IDLE.I m получение SyntaxError – user46646

+0

Команда, которую я дал, будет тем, что вы могли бы запустить из командной строки, а не из интерпретатора python. – vezult

0

Проверено на Windows, в Python 2.4 - вы можете попробовать сами.

>>> 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 
3

Чтобы узнать, сколько времени занимает импорт, самый простой способ, вероятно, с помощью timeit module ..

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

Так импортировать URLLIB 1 миллион раз, потребовалось чуть меньше второго (на Macbook Pro) ..

у меня есть мастер-скрипт, который импортирует другой modules.I нужно рассчитать, сколько времени это занимает

Если вы имеете в виду общее время выполнения скрипта, на 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)

+0

Умм, я не думаю, что это фактически импортирует не один раз. Это действительно просто проверка производительности кеша модулей Python. 'reload (module)' не имеет того же поведения, что и импорт с нуля. Чтобы действительно ответить на вопрос автора, на самом деле довольно сложно, если только время для импорта не является достаточно большим, чтобы измерить один звонок одновременно. –

6

Одним из способов импорта профилей является использование модуля profile_imports, используемого в bzr source code:

# 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) 

Помимо предоставления вам времени для импорта, это также оценивает время для компиляции регулярных выражений, что часто является значительной причиной замедления импорта.

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) 
Смежные вопросы