cProfiler:如何按执行顺序获取统计信息?

Posted

技术标签:

【中文标题】cProfiler:如何按执行顺序获取统计信息?【英文标题】:cProfiler: How to get stat by execution order? 【发布时间】:2014-03-03 11:56:29 【问题描述】:

我想获得探查器的统计信息,而不是按调用次数和花费的时间,而是按自然执行顺序排序和分组。

例如,如果我们将 cProfiler 用于下一个简单程序:

def my_sleep0():
    sleep( 0.05 )

def my_sleep1():
    sleep( 0.15 )
    my_sleep2()

def my_sleep2():
    my_sleep3()

def my_sleep3():
    sleep( 0.1 )


if __name__ == '__main__':

    p = Profiler( './' ) # a wrapper for cProfiler, cProfiler starts here

    i = 10

    for i in range( 1, 5 ):
        i += 100
        my_sleep0()
        my_sleep1()
        my_sleep1()

    # cProfiler destructs and ends here

我想要一个按自然执行顺序的统计,例如:

Ordered by: execution

calling_function    cumtime backtrace

test.py:36(my_sleep0)   <cumtime>  test.py:43()
test.py:39(my_sleep1)   <cumtime>  test.py:44()
test.py:43(my_sleep2)   <cumtime>  test.py:20 called by test.py:44(my_sleep1)
test.py:43(my_sleep3)   <cumtime>  test.py:25 called by test.py:20(my_sleep1)->test.py:26(my_sleep2)
test.py:39(my_sleep1)   <cumtime>  test.py:45()
test.py:43(my_sleep2)   <cumtime>  test.py:20 called by test.py:25(my_sleep1)
test.py:43(my_sleep3)   <cumtime>  test.py:25 called by test.py:20(my_sleep1)->test.py:26(my_sleep2)
...

&lt;cumtime&gt; 是一个数字时间。)

Python中有没有办法实现它?怎么样?

加法。

我的 Profiler() 代码现在不这样做:

class Profiler:
    def __init__( self, dir ):
        self._profiler = cProfile.Profile()
        self._profiler.enable()

        self._dir = dir # profiler output is "/tmp/profiler/key/<files_here>"


    def stop( self ):
        profilerDir = self._dir

        self._profiler.disable()

        with open( os.path.join( profilerDir, datetime.now().strftime( "%d-%m-%y %H.%M.%S" ) ), 'w' ) as f:
            stat = pstats.Stats( self._profiler, stream = f ).sort_stats( 'pcalls' )
            stat.print_stats()  
            stat.print_callers()
            stat.print_callees()


    def __del__( self ):
        self.stop()

【问题讨论】:

@KillianDS 好的。但似乎 cProfiler 没有该功能。我想知道是否有工具或方法可以实现我想要的。 可以按行排序。为什么要按(第一次?)执行时间排序?这对你有什么好处? @KillianDS 我想按执行顺序排序,而不是按执行时间排序。对不起。 是的,这就是我的意思,我仍然不明白你为什么要这样做(why 通常比how 更重要的信息,以便最终得到正确的回答)。 @KillianDS 我很难弄清楚some 是从哪里调用的。我想轻松地将探查器的统计信息与真实代码链接起来。这就像你在某个动作之前测量时间,然后在某个动作之后测量时间,然后将信息保存到一个统计文件中:时间差和当前调用堆栈。并且仅按此顺序 - 执行顺序。 【参考方案1】:

是的,但在许多情况下,这样做并不明智,因为代码的一个(慢)部分可能在执行过程中被多次调用,您可以做的是运行跟踪并使用该代码的输出对配置文件条目进行排序。

即trace 告诉您执行顺序,并可用于对配置文件数据进行排序。

为此,我会认真考虑查看个人资料查看器工具,例如 runsnakerun,例如下面让我看看花了多少时间以及从哪里调用它:

【讨论】:

谢谢。你知道怎么做吗?一个特殊的功能,方法不会慢很多? 正如我所说 - trace 会给你一个执行顺序 - 解析结果,其中包括文件、行、函数信息,以及那些用于配置文件的结果,其中包括文件、行函数信息和 排序执行顺序的配置文件结果。然后输出结果。在任何复杂的情况下,它几乎是无用的。 我可以在有很多用户的生产服务器上使用跟踪,有时会出现减速问题吗? 如果您在生产服务器上运行 a) 将运行复杂的代码,b) 可能甚至不应该运行分析器 & c) 受 python 代码之外的事物的支配分析器无法准确反映。 谢谢。实际上,我在生产服务器上启动了分析器,但仅针对我的用户(如果 user_id=my_user_id)。

以上是关于cProfiler:如何按执行顺序获取统计信息?的主要内容,如果未能解决你的问题,请参考以下文章

Python脚本性能剖析

了解 python cProfile 输出

promise执行顺序

Python流程控制-1 顺序执行

SQL语句执行流程与顺序原理解析

如何在一个循环执行ajax方法里面嵌套的ajax方法