返回介绍

2.1 高效地分析性能

发布于 2024-01-25 21:44:08 字数 1560 浏览 0 评论 0 收藏 0

性能分析的首要目标是对受测系统进行测试来发现哪里太慢(或占用太多RAM,或导致太多磁盘I/O或网络I/O)。性能分析一般会导致额外的性能开销(一般会慢10到100倍),但你依然希望你的代码尽可能像是在真正的环境中一样运行。所以要以测试用例的方式将你需要测试的那部分系统独立出来。最好这个测试用例已经使用了一套自己的模块。

本章介绍的第一个基本技术包括IPython的%timeit魔法函数,time.time(),以及一个计时修饰器。你可以使用这些技术来了解语句和函数的行为。

然后我们会学习cProfile(2.6节),告诉你如何使用这个内建工具来了解代码中哪些函数耗时最长。这将让你站在高处俯瞰你的问题,使你能够将注意力集中到关键函数上。

接下来,我们会去看line_profiler(2.8节),这个工具能够对你选定的函数进行逐行分析。其结果将包含每行被调用的次数以及每行花费的时间百分比。这恰能让你知道是哪里跑得慢以及为什么。

有了line_profiler的结果,你就有了足够的信息去使用编译器(第7章)。

在第6章(例6-8),你将学到如何使用perf stat命令来了解最终执行于CPU上的指令的个数以及CPU缓存的利用率。这让你能够进一步调优矩阵操作。读完本章后你应该去看看那个例子。

line_profiler之后,我们会演示heapy(2.10节),它可以追踪Python内存中所有的对象——这对于消灭奇怪的内存泄漏特别有用。如果你的系统需要持续运行,那么你会对dowser(2.11节)感兴趣,它让你能够通过一个Web浏览器界面审查一个持续运行的进程中的实时对象。

为了帮助你了解为什么你的RAM占用特别高,我们会给你演示memory_profiler(2.9节)。它能以图的形式展示RAM的使用情况随时间的变化,这样你就可以向你的同事们解释为什么某个函数占用了比预期更多的RAM。

 备忘 

无论你用什么方法分析代码性能,都必须记得用足够的单元测试覆盖你的代码。单元测试能帮助你避免愚蠢的错误并让你的结果可重现。没有单元测试风险极大。

在编译或重写你的算法之前始终进行性能分析。你需要证据来决定最有效的优化手段。

最后,我们还会给你介绍CPython中的Python字节码(2.12节),这样你就能够了解在其台面下发生了什么。具体来说,了解基于栈的Python虚拟机如何运行将帮助你明白为什么某个编程风格会跑得比别人慢。

在结束本章之前,我们会回顾如何在性能分析中集成单元测试(2.13节),让代码跑得更有效的同时维持正确。

最后我们将讨论性能分析的策略(2.14节),这样你就能够可靠地分析你的代码并收集正确的数据来验证你的假设。在这里,你将了解到动态CPU频率以及TurboBoost等特性能够如何歪曲你的性能分析结果以及如何禁用这些功能。

为了讲解所有这些步骤,我们需要以一个便于分析的函数为例。下一节我们介绍Julia集合。这是一个对RAM有一点饥渴的CPU密集型函数,而且它还具有非线性的行为(这样我们就无法轻易预测其结果),这意味着我们需要在运行时分析其性能而没法进行线下调查。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文