微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在循环中分析带有参数的方法?

如何解决如何在循环中分析带有参数的方法?

我有一个Foo,它实现了一个方法compute。我想看看compute花费了多长时间以及执行时花费了大部分时间。为了解决一个问题,我循环使用timeit.default_timer求平均值:

import numpy as np
from timeit import default_timer as Timer

foo = Foo()
n = int(10e8)
times = np.empty(n)

for i in range(n):
    start = Timer()
    foo.compute(i)
    times[i] = Timer() - start

print(np.sum(times) / times.size)

这告诉我每个compute调用的平均执行时间是多少,很容易;除了它比我想象的要慢。

现在,我想分解compute的执行配置文件,但是以下代码似乎无法解决问题:

import cProfile

for i in range(n):
    cProfile.run(foo.compute(i))

我认为无论如何它都不会起作用,但是文档似乎建议我必须将此循环放入方法中,然后再分析该循环?因此,我尝试了一下,但没有显示我想要的compute内部发生了什么。如何做到这一点?

解决方法

您可以使用run()而不是使用runctx(),它提供用于提供全局和本地字典的参数。

cProfile.runctx("foo.compute(n)",{"n": n,"foo": Foo()},{})

要汇总来自多个配置文件运行的结果,请参见https://web.dev/async-clipboard/

,

要使用cProfile,需要将函数作为字符串参数或“命令”传递。因此,只需修改原始代码即可:

for i in range(n):
    cProfile.run("foo.compute(i)")

但是,在您的情况下,您似乎想对“现实世界”情况的执行情况进行分析,并查看在哪里有可以优化的瓶颈。对功能进行性能分析与对功能进行基准测试不同。探查器上的Python documentation还指出:

请注意,探查器模块旨在为给定程序提供执行配置文件,而不是出于基准测试的目的(为此,有足够时间获得合理准确的结果)。

进行基准测试时,您希望循环执行多次命令,以便获得平均执行时间+-标准偏差,这应该代表实际情况,并允许您比较不同的解决方案。但是,分析会破坏该命令的单个运行。这样就足以确定该方法的哪些特定组件比其他组件花费更多的时间(相对于它们实际花费的时间为 ),并且这种数量级实际上不应在每次运行之间改变(尽管特定时间可能会有所波动。)

如果您确实想计算平均运行次数的统计信息,则可以生成许多运行次数的统计信息,然后提取数据以进行进一步处理:

pr = cProfile.Profile()
pr.enable()
 
for i in range(n):
    foo.compute(i)

pr.disable()
pr.create_stats()
stats = pr.stats

({pr.stats是一个字典,被格式化为配置文件时显示的打印语句)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。