如何在Python中查找代码的统计数据和执行时间

6

我是一名Python开发者,最近接触到了一些有关代码统计和执行时间的概念。

假设我有以下代码:

from time import gmtime, strftime
import timeit


def calculation():
     a = 2
     b = 3
     res = a + b
     return  res

if 'name' == 'main' :
    exec_time = timeit.timeit(calculation)
    print exec_time

结果:

0.2561519145965576

通过以上代码,我能够找到代码的执行时间,但是如何在Python中找到代码的统计信息呢?

我的目的是:

  1. 如何在Python中找到代码的统计信息
  2. 如何找到整个代码的执行时间
  3. 什么是代码的统计信息?

编辑后的代码:

例如,我将以上代码保存在文件test.py中。

现在,我使用以下命令运行上述文件:

python -m cProfile test.py

结果:

sh-4.2$ python -m cProfile test.py
         4 function calls in 0.001 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.001    0.001    0.001    0.001 test.py:1(<module>)
        1    0.000    0.000    0.000    0.000 timeit.py:105(Timer)
        1    0.001    0.001    0.001    0.001 timeit.py:53(<module>)
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

当我运行上述代码时,我需要像这样的东西,我想要做的是将打印统计信息的功能写入文件test.py,而不是从终端运行命令python -m cProfile test.py

至少我想在文件运行时找到函数calculation()的统计信息和执行时间,因为实际上函数calculation()具有执行某些操作的重要功能。


1
“代码统计”是什么意思? - Chris
2
你可能需要进行性能分析(这是进一步研究的关键词)。同时查看文档这个问题 - Lev Levitsky
@chris:这正是我的疑惑,我不知道为什么会被踩,我对此有疑问并向SO寻求帮助。 - Shiva Krishna Bavandla
我修改了我的代码,有人能够检查一下吗? - Shiva Krishna Bavandla
3个回答

4

看起来您想了解如何使用timeit模块的编程接口。有关文档可以在此处找到。您需要一个样本集进行统计,例如最小值、最大值、平均值等。这意味着您需要通过timeit模块中Timeit类的repeat方法多次运行calculate函数来获取样本集。

例如:

timer = timeit.Timer(calculation)
results = timer.timeit(10000)

实际上,我们可以通过将函数calucation()传递到Timer/timeit中来找到执行时间。好的,但是像我在上面编辑的代码中所提到的那样,如果我们需要统计数据怎么办?也就是说,如果我们将文件作为“python -m cProfile test.py”运行,我们将会获得与上述相同的所有输出信息(例如,有多少个函数调用等),但是我不想使用这个命令来运行文件,而是当我将文件作为“python test.py”运行时,它应该显示与上述相同的所有结果,这意味着我们需要在test.py文件中实现cprofile功能。 - Shiva Krishna Bavandla
是的,回答您的问题。在我上面的示例中,results包含所有10000个时间的列表。打印输出中的第一列是总调用次数,在我的示例中为10000,因为这是传递进去的值。第二列是总时间,它将是列表中值的总和,以此类推。 - Josh Heitzman

0

我认为您正在询问如何在代码中使用 cProfile。实际上,这非常容易。 cProfile.Profile 有两个未记录的方法:enabledisable,可用于启动和停止分析器。这意味着您可以轻松创建一个上下文管理器或装饰器。以下示例在一个对象中实现了这两个功能,并包括一种使用 pstat 模块处理和打印输出的方法。

import cProfile, pstats, functools

class profile:

    def __init__(self, filename=None):
        """
        If defined, output is written to *filename*, otherwise it
        is processed using *pstats* and printed to STDOUT.
        """
        self._filename = filename
        self._prof = cProfile.Profile()

    def __enter__(self):
        self._prof.enable()

    def __exit__(self, exc_type, exc_value, traceback):
        self._prof.disable()
        if self._filename is not None:
            self._prof.dump_stats(self._filename)
        else:
            stats = pstats.Stats(self._prof)
            self.print_stats(stats)

    def print_stats(self, stats):
        """
        This method processes the stats and prints them.
        """
        stats.strip_dirs().sort_stats('cumulative').print_stats(20)

    def __call__(self, func):
        self._func = func
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            with self:
                return func(*args, **kwargs)
        return wrapper

因此使用方法是:

@profile()
def calculation():
    a = 2
    b = 3
    res = a + b
    return  res

calculation()

或者

with profile('output_file.pstat'):
    calculation()

您可以根据需要更改print_stats以显示所需的输出。


0

有另一种方法可以找到代码的聚合统计信息。您可以使用此库查找平均值、中位数、标准偏差、总耗时和调用次数。

该库名为codetiming,来自realpython。

一个示例用例:

from codetiming import Timer
from humanfriendly import format_timespan
from loguru import logger


@Timer(name="my_func", text=lambda secs: f"my_func elapsed time: {format_timespan(secs)}")
def my_func():
    ...

def get_aggregated_timings(cls):
    timed_function = "my_func"
    logger.info(
        f"\n{timed_function} count: {Timer.timers.count(timed_function)}\n"
        f"total: {Timer.timers.total(timed_function)}\n"
        f"max: {Timer.timers.max(timed_function)}\n"
        f"min: {Timer.timers.min(timed_function)}\n"
        f"mean: {Timer.timers.mean(timed_function)}\n"
        f"standard deviation: {Timer.timers.stdev(timed_function)}\n"
        f"median: {Timer.timers.median(timed_function)}\n"
    )
    Timer.timers.clear()  # clears all the timer data


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接