最近写作业时, 发现numpy实在太慢了, 然后发现了对numpy进行加速的几种方法
- pypy: 适合原生python书写的程序, 对第三方库不是很友好
- cython: 需要换用非原生语言编写, 比较麻烦
- numba: 对numpy等数值运算的加速有奇效
numba 基础
Tips
- jit的加速有两种模式, lazy模式和eager模式, lazy模式直接在需要加速的函数前加上
@jit
装饰器即可, eager模式在函数前对函数的签名进行声明, 例如@jit(int32(int32, int32))
. - jit的加速有两个级别
- nopython模式: Numba编译模式,生成不访问Python C API的代码。 此编译模式生成最高性能代码,但要求可以推断函数中所有值的基本类型。 除非另有说明,否则如果不能使用nopython模式,
@ jit
装饰器将自动回退到object模式 - object模式:Numba编译模式,生成代码,将所有值作为Python对象处理,并使用Python C API对这些对象执行所有操作。 除非Numba编译器可以利用循环匹配,否则在对象模式下编译的代码通常不会比Python解释代码快
- nopython模式: Numba编译模式,生成不访问Python C API的代码。 此编译模式生成最高性能代码,但要求可以推断函数中所有值的基本类型。 除非另有说明,否则如果不能使用nopython模式,
- 因此当发现jit不能加速的时, 可以带上
@jit(nopython=True)
的参数, 它将会对造成不能使用nopython模式
的代码部分进行报错, 如果逻辑上可以修改过来的话, 就可以享受高性能的nopython模式了 - numba还有一个奇技淫巧, 可以摆脱GIL的束缚, 在装饰器带上
@jit(nogil=True)
. - numba可以指定把编译缓存保存下来, 但是目前的使用上, 感觉不出运行时间上的明显差异.
- numpy中可以定义2**256大小的整型, 但是numba对于超过64位的整型能跑,但没有加速,64位以下的整数可以加速,64位以上的出现警告就没有加速了. [感谢网友交流]