python边写边总结(十)Numba文档阅读记录
发布日期:2021-06-29 06:03:26 浏览次数:2 分类:技术文章

本文共 3093 字,大约阅读时间需要 10 分钟。

if your code is numerically orientated (does a lot of math), uses NumPy a lot and/or has a lot of loops, then Numba is often a good choice.

如果代码是数值计算,涉及大量的数学,运用了许多numpy的内容,并包含大量的循环,numba是一个很好的选择

from numba import jitimport numpy as npx=np.arrange(100).reshape(10,10)@jit(nopython=True)def go_fast(a):    trace = 0    for i in range(a.shape[0]):        trace+=np.tanh(a[i,i])    return a+traceprint(go_fast(x))

Numba里面介绍的测试方法,仍然是用time module

start=time.time()...end=time.time()print(end-start)

但是值得注意的是,因为它需要编译,也占用时间,所以第一次使用时,比较慢,再次使用时,就会加快速度

运用@jit的简单方式时,会让Numba自己决定如何取优化

from numba import jit@jitdef f(x, y):    # A somewhat trivial example    return x + y

但是也可以告诉Numba函数签名

from numba import jit,int32@jit(int32(int32,int32))df f(x,y):    return x+y# 注意这里参数类型,如果超出了int32类型的极限,将会有意外的事情发生

Numba有两个编译mode:nopython mode和objectmode.使用nopython mode可以产生更快的code

Whenever Numba optimizes Python code to native code that only works on native types and variables (rather than Python objects), it is not necessary anymore to hold Python’s (GIL). Numba will release the GIL when entering such a compiled function if you passed nogil=True.

每当Numba将Python代码优化为仅适用于本机类型和变量(而不是Python对象)的本机代码时,就不再需要持有Python的全局解释器锁(GIL)。 如果你传递了nogil = True,Numba会在输入这样的编译函数时释放GIL。

查看了GIL技术,它的存在在单核处理器上完全没问题,但是在多核处理器上,就会让执行效率降低,所以,Numba试图在编译后去掉python的GIL,以充分利用多核处理器的性能在这个博客里面完整的解释了这里面的问题所在

 

为了避免每次编译都需要调用一个python program,可以使用cache=True,将编译的结果放进file-based cache

@jit(cache=True)def f(x, y):    return x + y

parallel=True必须运用在已运用nopython=True之后的函数中

@jit(nopython=True, parallel=True)def f(x, y):    return x + y

以上讲的都是jit装饰器

我们再看看vectorize装饰器

Numba的vectorize允许Python函数将标量输入参数用作NumPy ufuncs。 创建传统的NumPy ufunc并不是最直接的过程,而是涉及编写一些C代码。 Numba让这很容易。 使用vectorize()装饰器,Numba可以将纯Python函数编译成一个ufunc,它在NumPy数组上运行的速度与用C编写的传统ufunc一样快

vectorize()有两个modes:

Eager,or decoration-time,compiilation:如果你传递一个或多个类型的签名给装饰器,你就可以创建一个ufunc

Lazy,or call-time,compilation:当你没有给任何签名,装饰器会给你一个Numba动态的 ufunc

注意这里的decoration-time和call-time,Lazy状态下就是没给签名,所以会在运行时,根据所给的参数类型自己确定,但是Eager则会根据所给的签名在编译时就确定

再看看guvectorize 装饰器

虽然vectorize()允许你编写一次处理一个元素的ufunc,但是guvectorize()装饰器将oncept更进一步,并允许你编写可以在任意数量的输入数组元素上工作的ufunc,并返回 不同维度的数组。 典型的例子是运行中值或卷积滤波器。

@guvectorize([(int64[:], int64, int64[:])], '(n),()->(n)')def g(x, y, res):    for i in range(x.shape[0]):        res[i] = x[i] + y

以上都是对函数进行装饰,还可以对类进行装饰,看看jitclass装饰器

Numba通过numba.jitclass()装饰器支持类的代码生成。 可以使用此装饰器标记类以进行优化,同时指定每个字段的类型。 我们将结果类对象称为jitclass。 jitclass的所有方法都被编译成nopython函数。 jitclass实例的数据在堆上作为C兼容结构分配,以便任何已编译的函数都可以绕过解释器直接访问底层数据。

import numpy as npfrom numba import jitclass          # import the decoratorfrom numba import int32, float32    # import the typesspec = [    ('value', int32),               # a simple scalar field    ('array', float32[:]),          # an array field]@jitclass(spec)class Bag(object):    def __init__(self, value):        self.value = value        self.array = np.zeros(value, dtype=np.float32)    @property    def size(self):        return self.array.size    def increment(self, val):        for i in range(self.size):            self.array[i] = val        return self.array

还没写完,明天继续

转载地址:https://blog.csdn.net/zhouzhouasishuijiao/article/details/85056009 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:python边写边总结(十一)Matplotlib了解
下一篇:python边用边总结(九)python的inspect

发表评论

最新留言

网站不错 人气很旺了 加油
[***.192.178.218]2024年04月02日 11时42分35秒