【问题标题】:python twisted : retrieve a deferred's execution timepython twisted:检索延迟的执行时间
【发布时间】:2010-10-27 17:25:50
【问题描述】:

我想知道从触发第一个回调到最终结果的延迟执行需要多长时间。

关于如何做到这一点的任何想法,可能是以非侵入性方式(意味着不修改任何回调函数以跟踪执行时间)?

【问题讨论】:

    标签: python twisted deferred


    【解决方案1】:

    如果您在“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】:

      猜你应该配置你的应用,按照这种方式:

      安装此工具http://kcachegrind.sourceforge.net/html/Home.html

      启动你扭曲的应用程序并收集原始数据:

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

      然后,您将“hotshot”转换为“calltree”,运行:

      hotshot2cg myapp.hotshot > myapp.calltree

      现在我们可以在 Kcachegrind 工具中查看调用树了。

      kcachegrind myapp.calltree

      使用此工具,您可以查看扭曲事件循环的调用图, 执行时间你可以看到百分比。 所以不需要打补丁,运行这个工具看看

      附:检查内存: How to use guppy/heapy for tracking down memory usage

      【讨论】:

      • hotshot2cg 命令提供了什么?我在 pip 或 brew 中找不到任何提及它,也没有在网上提及....
      • hotshot2cg 就像一个转换器,是 KCacheGrind 应用程序的一部分,所以应该先安装它。
      • 我无法运行 hotshot2cg,即使在安装了 kcache 研磨后也是如此。我找不到任何算法/软件来将 hotshot 转换为 calltree。投反对票。
      • @WaxCage 命令是“hotshot2calltree”。无论如何,hotshot(格式)似乎已经过时,取而代之的是 pstats,这是 cProfile 现在为您提供的。您可以使用pyprof2calltree 进行转换。
      【解决方案3】:

      分析对于我想要实现的目标来说有点矫枉过正。

      我最终得到的解决方案并不意味着对现有代码进行大量修改,但绝不是“通用的”:

      我的原始代码是这样的:

      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

      【讨论】:

      • @user304965:我很犹豫是否要给出这样的答案,主要是因为您必须对回调进行分析。如果您正在编写自己的代码,这是可能的。为此目的检测代码仍然很丑陋。但是如果你使用来自其他模块的回调,你甚至不能这样做。想法是回调会立即触发,但这取决于很多事情。
      猜你喜欢
      • 2011-09-23
      • 2011-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多