美文网首页
找到Python程序中执行最慢的代码

找到Python程序中执行最慢的代码

作者: welder77 | 来源:发表于2022-09-11 22:59 被阅读0次

这周我们在工作中又遇到了一个小问题。我们用Python完成了一个转换脚本,正常情况下,程序完成转换仅需要几秒,但在某些情况下,程序完成转换的速度非常慢,大约需要几分钟。所以我们非常好奇,程序到底做了什么会变得如此之慢?

经过一番查阅,我们找到了一款性能分析工具:pyinstrument ,通过它我们就能很方便的找到程序执行过程中,不同函数及代码的执行时间,进而找到程序执行慢的原因并优化我们的程序。

接下来我们就来看看它的使用方法吧。

首先还是安装:
pip install pyinstrument

安装后,Pyinstrument的使用方法,分为两种,一种是在终端里运行 pyinstrument 命令加参数来实现,另一种是直接在代码中嵌入分析代码。

我们先介绍直接在代码中嵌入分析代码的方法,这种方法相对比较灵活,也较常用。

假设,我们编写了以下一段采集音频并收集其主要频率及音量的代码 Demo.py

timer = 10  #记录时间
thres = 100 #阈值,越大过滤的内容越多
#读取波形文件
freq, all_array = wavfile.read("1k.wav")

#分析波形文件,并得到其中的主要频率及最大、平均音量
final_freq_list , vol_list =get_freq_vol(all_array,freq,thres=100, range_thres=20)

如果我们想知道,这段代码中,各语句执行的时间,我们只需要在执行代码前实例化Profiler并启动,在代码执行结束后停止Profiler并打印分析结果。

#导入pyinstrument并实例化Profiler分析器
from pyinstrument import Profiler
profiler = Profiler()
profiler.start()

timer = 10  #记录时间
thres = 100 #阈值,越大过滤的内容越多
#读取波形文件
freq, all_array = wavfile.read("1k.wav")

#分析波形文件,并得到其中的主要频率及最大、平均音量
final_freq_list , vol_list =get_freq_vol(all_array,freq,thres=100, range_thres=20)

#结束Profiler,并输出分析结果
profiler.stop()
profiler.print()

执行这段代码后,程序会输出如下结果。

image.png

pyinstrument 的分析结果默认是按照代码执行的时间的快慢来排序的,依次是从慢到快,所以我们能很快定位到整个程序执行最慢的代码,是get_freq_vol中的fft函数。
由于fft是第三方库的内建函数,所以pyinstrument 默认会隐藏针对这个函数的细节,如果想查看细节的话,也可以在代码最后加入如下语句profiler.open_in_browser(),这样程序运行结束后,pyinstrument 会输出结果到html中,并自动通过浏览器打开它。

在浏览器中,我们就可以展开并查看这些隐藏的细节了。


image.png

接着,简单介绍下终端运行的方法,我们可以直接在Dos窗口中通过pyinstrument [options] scriptfile [arg]的方式,让Pyinstrument对某个py文件进行性能分析并输出结果 ,
下面的命令,是让Pyinstrument对demo.py进行分析,并输出结果到HTML文件中:
pyinstrument --outfile=demo.html -r html demo.py

以下是pyinstrument 支持的命令行参数:

Usage: pyinstrument [options] scriptfile [arg] ...

Options:
  --version             show program's version number and exit
  -h, --help            show this help message and exit
  --load-prev=ID        Instead of running a script, load a previous report
  -m MODULE_NAME        run library module as a script, like 'python -m
                        module'
  -o OUTFILE, --outfile=OUTFILE
                        save to <outfile>
  -r RENDERER, --renderer=RENDERER
                        how the report should be rendered. One of: 'text',
                        'html', 'json', or python import path to a renderer
                        class
  -t, --timeline        render as a timeline - preserve ordering and don't
                        condense repeated calls
  --hide=EXPR           glob-style pattern matching the file paths whose
                        frames to hide. Defaults to '*/lib/*'.
  --hide-regex=REGEX    regex matching the file paths whose frames to hide.
                        Useful if --hide doesn't give enough control.
  --show=EXPR           glob-style pattern matching the file paths whose
                        frames to show, regardless of --hide or --hide-regex.
                        For example, use --show '*/<library>/*' to show frames
                        within a library that would otherwise be hidden.
  --show-regex=REGEX    regex matching the file paths whose frames to always
                        show. Useful if --show doesn't give enough control.
  --show-all            show everything
  --unicode             (text renderer only) force unicode text output
  --no-unicode          (text renderer only) force ascii text output
  --color               (text renderer only) force ansi color text output
  --no-color            (text renderer only) force no color text output

总结,在优化程序运行速度时, pyinstrument起到了重要的分析作用。我们只有先定位到程序执行慢的代码,才能找到其慢的原因,再根据原因来指定优化方案。

相关文章

网友评论

      本文标题:找到Python程序中执行最慢的代码

      本文链接:https://www.haomeiwen.com/subject/wwyfortx.html