CDA数据分析师(CDA.cn)——真本事,心舒适
加快Python算法的四个方法(二)Numba
相信大家在做一些算法经常会被庞大的数据量所造成的超多计算量需要的时间而折磨的痛苦不已,接下来我们围绕四个方法来帮助大家加快一下Python的计算时间,减少大家在算法上的等待时间。今天给大家介绍Numba这一块的内容。
1.简介
所以什么是Numba呢?Numba是Python的即时编译器,也就是说当你调用Python 函数时,你的全部或部分代码都会被计时转换成为机器码进行执行,然后它就会以你的本机机器码速度运行,Numba由Anaconda公司赞助,并得到了许多组织的支持。
使用Numba,你可以加速所有以集中计算的、计算量大的python函数(例如循环)的速度。它还支持numpy库!因此,你也可以在计算中使用numpy,并加快整体计算的速度,因为python中的循环非常慢。你还可以使用python标准库中的数学库的许多功能,例如sqrt等。
CDA数据分析师(CDA.cn)——真本事,心舒适
2.为什么选择Numba?
所以,为什么要选择Numba?特别是当存在有许多其他编译器,例如cython或任何其他类似的编译器,或类似pypy的东西时。
选择Numba的理由很简单,那就是因为你不需要离开使用Python编写代码的舒适区。是的,你没看错,你不需要为了加速数据的运行速度而改变你的代码,这与从具有类型定义的相似cython代码获得的加速相当。那不是更好么?
你只需要在函数周围添加一个熟悉的Python功能,也就是装饰器(包装器)。目前类的装饰器也在开发之中。
所以,你只需要添加一个装饰器就可以了。例如:
from numba import jit @jit
def function(x):
# 循环或数值密集型的计算 return x
它看起来仍然像是纯python代码,不是吗?
3. Numba如何工作?
Numb使用LLVM编译器基础结构,从纯Python代码生成优化的机器码。使用Numba的代码运行速度与C,C ++或Fortran中的类似代码相媲美。 这是代码的编译方式:
CDA数据分析师(CDA.cn)——真本事,心舒适
首先,获取,优化Python函数并将其转换为Numba的中间表示形式,然后类似于Numpy的类型推断一样进行类型判断(因此python float为float64),然后将其转换为LLVM可解释的代码。然后,该代码被馈送到LLVM的即时编译器以发出机器代码。 你可以根据需要在运行时生成代码或在CPU(默认)或GPU上导入代码。
4.使用基本的Numba功能(只需要@jit!)
小菜一碟!
为了获得最佳的性能,numba建议在你的jit包装器中使用参数nopython = True,但它根本不会使用Python解释器。或者你也可以使用@njit。如果你使用nopython = True的包装器失败并出现错误,则可以使用简单的@jit包装器,该包装器将编译部分代码,对其进行循环,然后将其转换为函数,再编译为机器码,然后将其余部分交给python解释器。 因此,你只需要执行以下操作:
from numba import njit, jit
@njit # 或者@jit(nopython=True) def function(a, b): # 循环或数值密集型计算 return result
CDA数据分析师(CDA.cn)——真本事,心舒适
使用@jit时,请确保你的代码具有Numba可以编译的内容,例如计算密集型循环,使用它支持的库(Numpy)及其支持的函数。否则,它将无法编译任何内容。
首先,numba在首次用作机器代码后还会缓存这些函数。因此,在第一次使用之后,它会变得更快,因为你无需再次编译该代码,因为你使用的参数类型和你之前使用的相同。 而且,如果你的代码是可以并行化运行的,那么也可以将parallel = True作为参数传递,但是必须跟参数nopython = True结合使用。目前,它仅可以在CPU上工作。
你也可以指定你想要的函数签名,但是它不会编译你给他的任何其他类型的参数,比如: 你还可以指定你希望函数具有的函数签名,但是对于提供给它的任何其他类型的参数,它将不会编译。例如:
from numba import jit, int32 @jit(int32(int32, int32)) def function(a, b): #循环或数值型密集型计算 return result
#或者你还没有导入类型的名称 #你可以将他们作为字符串传递
@jit('int32(int32, int32)') def function(a, b): #循环或数值型密集型计算 return result
现在,你的函数将只接受两个int32并返回一个int32。这样,你可以更好地控制自己的函数。你甚至可以根据需要传递多个)函数签名。
CDA数据分析师(CDA.cn)——真本事,心舒适
你还可以使用numba提供的其他装饰器:
1. @vectorize:允许将标量参数用作numpy ufunc, 2. @guvectorize:产生NumPy广义ufuncs 3. @stencil:将函数声明为类似模板操作的内核, 4. @jitclass:对于支持jit的类,
5. @cfunc:声明一个用作本机回调的函数(从C / C ++等调用), 6. @overload:注册自己的函数实现以在nopython模式下使用,例如
@overload(scipy.special.j0)。
Numba还具有预先(AOT)编译功能,它生成一个编译后的扩展模块,该模块不依赖于Numba。但:
1. 它只允许使用常规函数(不能使用ufuncs),