《Python高性能编程》——2.14 确保性能分析成功的策略

2.14 确保性能分析成功的策略

性能分析需要一些时间和精力。如果你把需要测试的代码段跟你代码的主体分离,你会有一个更好的机会去了解你的代码。然后你可以用单元测试来保证正确性,你还可以传入精心编造的真实数据来测试算法的有效性。

记得关闭任何基于BIOS的加速器,因为它们只会混淆你的结果。Ian的笔记本电脑使用的Intel TurboBoost功能可以在温度足够低的时候将CPU暂时加至极速。这意味着低温时运行同一段代码的速度可能比高温时要快。你的操作系统也许还控制了时钟的速度——使用电池电源的笔记本可能比插了主电源时更积极地控制CPU的速度。为了建立一个更加稳定的测试配置,我们:

  • 在BIOS上禁用了TurboBoost。
  • 禁用了操作系统改写SpeedStep(如果你有权限,你可以在你的BIOS中找到它)的能力。
  • 只使用主电源(从不使用电池电源)。
  • 运行实验时禁用后台工具如备份和Dropbox。
  • 多次运行实验来获得一个稳定的测量结果。
  • 如果可能,降至run level 1(UNIX),确保没有其他任务运行。
  • 重启并重跑实验来二次验证结果。

试着假设你代码的行为并用性能分析的结果来证实(或证伪)你的假设。你的选择不会改变(因为你的决定只能基于性能分析后的结果),但是你对代码的直觉了解会提升,而这会在今后的项目中带来好处,因为你会变得更能做出高效的决定。当然,你依然需要性能分析来验证这些高效的决定。

不要克扣准备工作。如果你在测试一段深入大型项目的代码前不先将代码分离,你很有可能会因为一些副作用而让你的努力偏离正轨。当你进行细粒度的改动时,对大型项目进行单元测试往往会更困难,而这又会更进一步妨碍你的努力。副作用可能包括其他线程或进程影响了CPU和内存的使用以及网络和磁盘的活动,这些都会歪曲你的结果。

对于Web服务器,推荐dowser和dozer;你可以用它们来将名字空间中的对象行为实时可视化。如果可能,一定要将你想测试的代码从Web应用的主体上分离出来,这会让性能分析方便太多。

确保你的单元测试覆盖了所有你想要分析的代码路径。任何你没有测过的东西都有可能带来细微的错误拖慢你的进度。使用coverage.py来确认你的测试覆盖了所有的代码路径。

对一个生成很多数字输出的复杂代码段进行单元测试可能会很困难。不要害怕将结果输出到一个文本文件来运行diff或者使用一个pickled对象。对于数字优化的问题,Ian喜欢创建一个包含了大量浮点数的长文本文件并使用diff——细小的取整问题会立刻显现,哪怕它们在输出中很罕见。

如果你的代码容易受到数字取整问题的影响,那么你最好有一个大的输出可以用来进行前后对比。取整错误的一个原因是CPU寄存器和主存之间的浮点精度不同。你的代码在不同的代码路径上运行可能导致细微的取整错误并在之后给你带来困扰——所以最好在它们刚发生的时候就尽早意识到这点。

显然,在性能分析和优化时使用源代码控制工具是很有意义的。创建新的代码分支代价很低,而且它能让你保持头脑清醒。

时间: 2025-01-05 01:53:47

《Python高性能编程》——2.14 确保性能分析成功的策略的相关文章

《Python高性能编程》——导读

前 言 Python很容易学.你之所以阅读本书可能是因为你的代码现在能够正确运行,而你希望它能跑得更快.你可以很轻松地修改代码,反复地实现你的想法,你对这一点很满意.但能够轻松实现和代码跑得够快之间的取舍却是一个世人皆知且令人惋惜的现象.而这个问题其实是可以解决的. 有些人想要让顺序执行的过程跑得更快.有些人需要利用多核架构.集群,或者图形处理单元的优势来解决他们的问题.有些人需要可伸缩系统在保证可靠性的前提下酌情或根据资金多少处理更多或更少的工作.有些人意识到他们的编程技巧,通常是来自其他语言

《Python高性能编程》——第2章 通过性能分析找到瓶颈 2.1 高效地分析性能

第2章 通过性能分析找到瓶颈 读完本章之后你将能够回答下列问题 如何找到代码中速度和RAM的瓶颈? 如何分析CPU和内存使用情况? 我应该分析到什么深度? 如何分析一个长期运行的应用程序? 在CPython台面下发生了什么? 如何在调整性能的同时确保功能的正确? 性能分析帮助我们找到瓶颈,让我们在性能调优方面做到事半功倍.性能调优包括在速度上巨大的提升以及减少资源的占用,也就是说让你的代码能够跑得"足够快"以及"足够瘦".性能分析能够让你用最小的代价做出最实用的决定

《Python高性能编程》——2.6 使用cProfile模块

2.6 使用cProfile模块 cProfile是一个标准库内建的分析工具.它钩入CPython的虚拟机来测量其每一个函数运行所花费的时间.这一技术会引入一个巨大的开销,但你会获得更多的信息.有时这些额外的信息会给你的代码带来令人惊讶的发现. cProfile是标准库内建的三个分析工具之一,另外两个是hotshot和profile.hotshot还处于实验阶段,profile则是原始的纯Python分析器.cProfile具有跟profile一样的接口,且是默认的分析工具.如果你对这些库的历史

《Python高性能编程》——1.2 将基本的元素组装到一起

1.2 将基本的元素组装到一起 仅理解计算机的基本组成部分并不足以理解高性能编程的问题.所有这些组件的互动与合作还会引入新的复杂度.本段将研究一些样本问题,描述理想的解决方案以及Python如何实现它们. 警告:本段可能看上去让人绝望--大多数问题似乎都证明Python并不适合解决性能问题.这不是真的,原因有两点.首先,在所有这些"高性能计算要素"中,我们忽视了一个至关重要的要素:开发者.原生Python在性能上欠缺的功能会被迅速开发出来.另外,我们会在本书中介绍各种模块和原理来帮助减

《Python高性能编程》——第1章 理解高性能Python 1.1 基本的计算机系统

第1章 理解高性能Python 读完本章之后你将能够回答下列问题 计算机架构有哪些元素? 常见的计算机架构有哪些? 计算机架构在Python中的抽象表达是什么? 实现高性能Python代码的障碍在哪里? 性能问题有哪些种类? 计算机编程可以被认为是以特定的方式进行数据的移动和转换来得到某种结果.然而这些操作有时间上的开销.因此,高性能编程可以被认为是通过降低开销(比如撰写更高效的代码)或改变操作方式(比如寻找一种更合适的算法)来让这些操作的代价最小化. 数据的移动发生在实际的硬件上,我们可以通过

《Python高性能编程》——2.3 计算完整的Julia集合

2.3 计算完整的Julia集合 我们在本节分解Julia集合的生成代码.我们将在本章以各种方法分析它.如例2-1所示,在模块的一开始,我们导入time模块作为我们的第一种分析手段并定义一些坐标常量. 例2-1 定义空间坐标的全局常量 """Julia set generator without optional PIL-based image drawing""" import time # area of complex space to i

python网络编程之数据传输UDP实例分析

  本文实例讲述了python网络编程之数据传输UDP实现方法.分享给大家供大家参考.具体分析如下: 一.问题: 你觉得网络上像msn,qq之类的工具在多台机器之间互相传输数据神秘吗?你也想玩一下在两台机器之间传数据吗?今天让python告诉我们基本原理吧,当然只是做简单的了解,实际情况复杂的多. 我们今天用python实现一个简单的udp程序. 二.程序实现: 1) 使用模块 (socket)套接字模块: 套接字模块是一个非常简单的基于对象的接口,它提供对低层BSD套接字样式网络的访问 .使用

《Python高性能编程》——2.12 用dis模块检查CPython字节码

2.12 用dis模块检查CPython字节码 到目前为止我们已经展示了很多测量Python代码开销的方法(包括CPU和RAM的开销).不过,我们还没有看到在底层虚拟机的字节码层面发生的事情.了解"台面下"发生的事情有助于在脑海中对运行慢的函数建立一个模型,并能帮助你编译你的代码.所以现在让我们来看一些字节码. dis模块让我们能够看到基于栈的CPython虚拟机中运行的字节码.在你的Python代码运行的时候,了解虚拟机中发生了什么可以帮助你了解为什么某些编码风格会比其他的更快.同时

《Python高性能编程》——2.13 在优化期间进行单元测试保持代码的正确性

2.13 在优化期间进行单元测试保持代码的正确性 如果你不对你的代码进行单元测试,那么从长远来看你可能正在损害你的生产力.Ian(脸红)十分尴尬地提到有一次他花了一整天的时间优化他的代码,因为嫌麻烦所以他禁用了单元测试,最后却发现那个显著的速度提升只是因为他破坏了需要优化的那段算法.这样的错误你一次都不要犯. 除了单元测试,你还应该坚定地考虑使用coverage.py.它会检查有哪些代码行被你的测试所覆盖并找出那些没有被覆盖的代码.这可以让你迅速知道你是否测试了你想要优化的代码,那么在优化过程中