витой питон: получить время выполнения отложенного - PullRequest
3 голосов
/ 27 октября 2010

Я хотел бы знать, сколько времени занимает выполнение Отложенного, с момента запуска первого обратного вызова до конечного результата.

Любые идеи о том, как это сделать, возможно, неинвазивным способом (имеется в виду отсутствие изменений в любой из функций обратного вызова для отслеживания времени выполнения)?

Ответы [ 3 ]

7 голосов
/ 27 октября 2010

Если вы запускаете свою программу с помощью «twistd», то у нее есть опция «--profile», которая может помочь вам с профилированием витого кода.

twistd "other options" --profile=statsfile --profiler=cProfile --savestats

И для просмотра статистики:

import pstats
stats = pstats.Stats('statsfile')
stats.sort_stats('time').print_stats()

Обратные вызовы выполняются сразу после срабатывания отложенных.Но немедленно означает, что каждый обратный вызов в отложенной цепочке должен быть выполнен, и у них будет свое время выполнения.Также различные части кода будут иметь свой собственный интервал времени для выполнения, включая цикл реактора.

Так сказать слово - сразу значит сказать как можно скорее.

Рассмотрим следующий плохой пример:

from twisted.internet import reactor, defer
import time

def timeit(func):
    def wrapper(*arg):
        t1 = time.time()
        res = func(*arg)
        t2 = time.time()
        print '%s took %0.3f ms' % (func.func_name, (t2-t1)*1000.0)
        return res
    return wrapper

d = defer.Deferred()

@timeit
def callfunc1(result):
    print 'XXXXX'

@timeit   
def callfunc2(result):
    print 'YYYYY'

d.addCallback(callfunc1)   
d.addCallback(callfunc2)  
t1 = time.time()
d.callback(True)
t2 = time.time()
print '%0.3f ms' % ((t2-t1)*1000.0)

Вывод:

XXXXX
callfunc1 took 0.039 ms
YYYYY
callfunc2 took 0.005 ms
0.108 ms

Теперь, если мы настроим вышеприведенный код, добавим в него реактор и callLater

2 голосов
/ 15 марта 2013

Думаю, вы должны профилировать свое приложение, следуйте по этому пути:

установить этот инструмент http://kcachegrind.sourceforge.net/html/Home.html

запустите ваше скрученное приложение и соберите необработанные данные:

twistd --savestats -n --profile = myapp.hotshot myapp

чем, вы конвертируете 'hotshot' в 'calltree', запустите:

hotshot2cg myapp.hotshot> myapp.calltree

теперь мы можем просматривать calltree в инструменте Kcachegrind.

kcachegrind myapp.calltree

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

P.S. для проверки памяти: Как использовать гуппи / heapy для отслеживания использования памяти

1 голос
/ 28 октября 2010

Профилирование - это немного излишне для того, чего я хотел бы достичь.

В итоге я нашел решение, которое не подразумевало серьезных изменений в существующем коде, но никоим образом не "универсально":

мой оригинальный код был что-то вроде:

def myfunc(*args):
    d = Deferred()
    d.addCallback(cb1)
    ...
    d.addCallback(lambda x: MyObject(x))

У меня теперь есть:

def myfunc(*args):
    init_time = time.time()
    d = Deferred()
    d.addCallback(cb1)
    ...
    d.addCallback(lambda x: MyObject(x, init_time))

class MyObject:
    def __init__(self, *args):
        ...
        self.exec_time = time.time() - init_time

Он делает то, что я хочу, но я надеялся, что структура Deferred представитчто-то, отслеживающее время выполнения, вместо того, чтобы возиться с моими объектами.Исходя из исходного кода я вижу, что такая вещь недоступна: http://twistedmatrix.com/trac/browser/tags/releases/twisted-10.0.0/twisted/internet/defer.py#L137

...