Python 中的快速性能分析
介绍
这是我使用Python来分析和加速代码的“高级”方法。这绝不是一种详尽的方法,而且很可能只会指出一些可以快速轻松地加速代码的地方。
该方法对于分析任何代码来说都是相当标准的:从顶层开始,然后有条不紊地沿着代码库向下工作以找到瓶颈。
这种方法旨在快速找到最明显的性能瓶颈,让您重新开始编码。幸运的是,定期对您的代码进行测试并尽早发现一些痛点是相当容易的。
将此过程的一部分自动化到持续集成服务器中以查找性能回归会很有用,但这是一个完全不同的指南。
第一步:概述整个申请
第一步是使用内置分析器运行脚本/应用程序,并确保强调较慢或更有趣的代码部分:
`python -m cProfile -o stats <my_awesome_code>.py`
接下来,退出应用程序并使用这个小脚本来查看大部分运行时间花费在哪里:
gist 4272487
该脚本将输出您的应用程序执行的所有函数调用,并按累计时间进行排序。
第二步:减少对昂贵代码的调用
此配置文件输出表示大部分处理时间花在何处。此时这可能有用也可能没用,但它可以提供一些线索。
- 查看percall列
- 是否有任何特定函数在一次调用中占用大量时间?
- 查看ncalls列
- 您能减少调用这个函数的次数吗?
第三步:专注于单一功能
第一步和第二步可能没有带来任何有用的性能提升。因此,现在是时候降低一个级别并缩小到要关注的单个功能了。
再看一下第一步的分析输出。找到percall列最大的函数。现在,分析此函数中的每一行,看看是否有可以轻松重构的慢代码。
此步骤需要一些额外的分析工具:
您可以在此处找到有关上述内容的一些文档。总的来说,我发现这些使用起来有点不方便,文档也有点缺乏。幸运的是,这种简单的分析方法不需要太多文档。
第一步,也可能是最棘手的一步,就是将@profile装饰器放在您想要分析的函数周围。别担心, @profile没什么可导入的,因为它很神奇。
我在尝试同时在多个函数上使用@profile时遇到了问题。
我希望@profile能以不同的方式实现。将其插入__builtins__的魔力确实让我感到困惑。
接下来,使用您的脚本/应用程序作为参数运行kernprof.py脚本:
`kernprof.py -v -l <script> <your_script_args>`.
现在,执行将导致分析函数运行的操作。
最后,我们可以使用line_profiler模块查看结果。上面调用kernprof.py脚本创建了一个分析器数据文件,通常名为<your_profiled_script>.lprof。
将此数据文件提供给line_profiler模块,它将按行细分打印函数的时间:
`python -m line_profiler <data_file>`
此时,就时间和%时间列而言,您可能会看到几行引人注目的内容。根据我的经验,此级别的缓慢往往类似于构建包含大量元素的列表,不断在大型列表中查找某个项目的存在,以及处理大型可迭代对象的其他操作。
第四步:回归基础
示例优化
这是一个相当经典的案例,但你会惊讶于它出现的频率。
例如,考虑一段代码,它花费大量时间在紧密循环中的大型列表中查找某个对象是否存在。这时就非常适合使用字典。
字典将大大缩短您的查找时间,但会浪费更多内存。这是典型的权衡,只有您才能根据应用程序的情况决定增加内存使用量是否值得。
还是很慢吗?
正如我在开头提到的,这种方法可能会让您需要更快的速度。幸运的是,还有几种选择。
-
- Cython 是加速 Python 代码的常用方法。它提供了一种向现有代码添加数据类型信息的方法,以及其他使代码更接近C层的机制。
-
- PyPy 是Python 语言规范的替代实现。简而言之,PyPy 是用 Python 实现的 Python。对 PyPy 的真正解释超出了本指南和我的专业知识范围。但是,如果您对语言和一些严肃的计算机科学感兴趣,您绝对应该研究一下。它会测试您的思维过程,这始终是一件好事。
-
- Numba 是一个类似于Cython的概念。它使用广受欢迎的LLVM编译器工具链来实现超快的结果。Numba 的另一个好处是它是由Continuum Analytics的优秀人员编写的。因此,Numba 背后有科学 Python 社区和numpy的一些创始人。这个项目还比较年轻,但我对它未来会有大作为抱有期待。
注意事项
存储 I/O、网络 I/O 等一些瓶颈不会轻易通过这种类型的分析显示出来。这种方法是一种快速分析和修复CPU 密集型任务的方法。
结论
分析和优化是一个非常复杂的主题,所以我的简单方法只是触及了皮毛。如果你想成为一名更好的程序员,你肯定会想更多地了解这个主题。幸运的是,有一些关于这个主题的精彩演讲可以帮助你从真正的专家那里学到更多。
免责声明:本内容来源于第三方作者授权、网友推荐或互联网整理,旨在为广大用户提供学习与参考之用。所有文本和图片版权归原创网站或作者本人所有,其观点并不代表本站立场。如有任何版权侵犯或转载不当之情况,请与我们取得联系,我们将尽快进行相关处理与修改。感谢您的理解与支持!
请先 登录后发表评论 ~