- 内容提要
- 前言
- 作者简介
- 封面简介
- 第1章 理解高性能 Python
- 第2章 通过性能分析找到瓶颈
- 2.1 高效地分析性能
- 2.2 Julia 集合的介绍
- 2.3 计算完整的 Julia 集合
- 2.4 计时的简单方法——打印和修饰
- 2.5 用 UNIX 的 time 命令进行简单的计时
- 2.6 使用 cProfile 模块
- 2.7 用 runsnakerun 对 cProfile 的输出进行可视化
- 2.8 用 line_profiler 进行逐行分析
- 2.9 用 memory_profiler 诊断内存的用量
- 2.10 用 heapy 调查堆上的对象
- 2.11 用 dowser 实时画出变量的实例
- 2.12 用 dis 模块检查 CPython 字节码
- 2.13 在优化期间进行单元测试保持代码的正确性
- 2.14 确保性能分析成功的策略
- 2.15 小结
- 第3章 列表和元组
- 第4章 字典和集合
- 第5章 迭代器和生成器
- 第6章 矩阵和矢量计算
- 第7章 编译成 C
- 第8章 并发
- 第9章 multiprocessing 模块
- 第10章 集群和工作队列
- 第11章 使用更少的 RAM
- 第12章 现场教训
7.9 Numba
来自Continuum Analytics的Numba是一个专用于numpy代码的即时编译器,在运行时由LLVM编译器(不是由我们在之前例子中所用的g++或gcc)来编译。它不需要预编译扫描,所以当你用它来运行新代码时,它会根据你的硬件编译每一个注解的函数。漂亮之处就是你提供了一个装饰器告诉它需要集中于哪些函数,接着你就让Numba接手。它的目标是在所有标准numpy代码上运行。
这是一个更年轻的项目(我们使用v0.13),它的API可能会随着每一次发布发生小小的改变,所以认为当前它在研究环境中更有用。如果你使用numpy array,并且有迭代许多次的非向量代码,Numba会给你一个快速而不需付出什么代价的胜利。
使用Numba的一个缺点就是工具链——它使用了LLVM,具有很多的依赖性。我们推荐你使用Continuum的Anaconda发布包,因为它提供了所有一切,否则在一个全新的环境中安装Numba是一个很耗时的任务。
例7-14展示了给我们的核心Julia函数增加@jit装饰器。这就是所需的全部了,numba被导入的事实意味着LLVM机制会在运行时发挥作用,在幕后编译这个函数。
例7-14 让函数应用@jit装修器
from numba import jit ... @jit() def calculate_z_serial_purepython(maxiter, zs, cs, output):
如果移除了@jit装饰器,那么这只是用Python2.7运行的Julia演示版的numpy版本,它花费了71秒。增加@jit装饰器后执行时间降低到0.3秒。这已经很接近我们用Cython达成的结果了,然而又没有多出注解的工作量。
如果我们在同一个Python会话中第2次去运行相同的函数,它甚至跑得更快——如果参数类型一样的话就不需要去编译目标函数了,所以整体执行速度就更快。第2次Numba的运行结果等价于我们之前一起使用Cython和numpy获得的结果(所以它几乎不需要做什么就可以达到与Cython一样快的结果!)。PyPy有同样的热身需要。
当用Numba去调试时,值得注意的是你可以让Numba去显示在一个编译函数内部的正在处理的变量类型。在例7-15中,我们可以看到zs被JIT编译器识别为一个复杂的数组。
例7-15 调试推导出的类型
print("zs has type:", numba.typeof(zs)) array(complex128, 1d, C))
Numba也支持其他形式的自省,比如inspect_types,从而让你可以检查编译代码去看看类型信息在哪里被推导出来。如果类型丢失了,那你就能细化函数的表达方式去帮助Numba得到发现更多的类型推导的机会。
Numba的高级版本,NumbaPro,可以实验性的用OpenMP支持prange并行操作符。实验性的GPU之处也有。这个项目的目标是很轻松地把使用numpy的更慢的Python循环代码转换为运行快速的代码,能在CPU或GPU上运行,这个可以关注一下。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论