zoukankan      html  css  js  c++  java
  • Numba 开发手册(一)

    网址:http://numba.pydata.org/numba-doc/latest/user/index.html

    一、5分钟quick start

    Numba是一个python的即时编译器,其使用Numpy的arrays,functions和loops。当调用Numba修饰函数时,它被编译为机器代码即时执行,并且全部或部分代码随后可以以本机机器代码速度运行!(大概意思是部分代码给编译了,不是像之前一样解释运行)

    注意:现在numba还在armv7l, armv8l (aarch64)平台上实验,在AMD ROC(GPU)也处于实验状态。

    判断什么情况下比较适合使用Numba:

    如果代码是使用numpy做数字运算,并且常常有很多的循环,那么使用Numba就是一个很好的选择。

    下面是Numba适合和不适合应用场景的示例:

    from numba import jit
    import numpy as np
    
    x = np.arange(100).reshape(10, 10)
    
    @jit(nopython=True) # Set "nopython" mode for best performance, equivalent to @njit
    def go_fast(a): # Function is compiled to machine code when called the first time
        trace = 0
        for i in range(a.shape[0]):   # Numba likes loops
            trace += np.tanh(a[i, i]) # Numba likes NumPy functions
        return a + trace              # Numba likes NumPy broadcasting
    
    print(go_fast(x))

    从上面的示例可以看出,Numba适合numpy中的循环操作、numpy函数以及broadcasting。

    from numba import jit
    import pandas as pd
    
    x = {'a': [1, 2, 3], 'b': [20, 30, 40]}
    
    @jit
    def use_pandas(a): # Function will not benefit from Numba jit
        df = pd.DataFrame.from_dict(a) # Numba doesn't know about pd.DataFrame
        df += 1                        # Numba doesn't understand what this is
        return df.cov()                # or this!
    
    print(use_pandas(x))

    从上面这个例子可以看出numba不适合字典型变量和一些非numpy的函数,尤其是上面numba不能解析pandas,上面的函数内容在运行时也就无法编译。

    关于nopython模式:

    Numba中的@jit运算符能按照两种编译模式运行,nopython模式和object模式。例如上面的go_fast函数,nopython=true,将@jit设置为nopython模式。nopython编译模式的行为本质上是编译装饰函数,以便它完全运行而不需要Python解释器的参与。这是使用Numba jit装饰器的推荐和最佳实践方式,因为它可以带来最佳性能。

    如果nopython模式下的编译失败,Numba可以使用对象模式进行编译,如果未设置nopython = True,则这是@jit装饰器的fall back模式(如上面的use_pandas示例中所示)。在这种模式下,Numba将识别它可以编译的循环,并将它们编译成在机器代码中运行的函数,并且它将运行解释器中的其余代码。为获得最佳性能,请避免使用此模式。

    如何去衡量Numba的性能:

    首先,numba在第一次执行的时候会执行函数编译为机器代码,这是需要耗时的,但是后面numba会将编译好的机器代码缓存起来以供后面的循环调用。

    注意一个地方,如果编译时间很长,那么numba是支持将编译好的函数存到disk上的。

    Numba是如何工作的:

    Numba读取了@jit函数的python字节,并且分析优化代码,最后使用LLVM编译器生成函数的机器代码。

    Numba中的decorators:

    @njit @njit(nopython=true)的简称
       
       
       
       
       
       
       
       
       

     二、安装

    安装完成以后,可以使用 numba-s 命令报告整个系统的信息。(是在命令行里面)

    三、编译python代码,使用@jit

    基本使用

    1、Lazy compilation

    使用@jit的推荐方式为使用numba去决定如何去优化:

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

    在这种模式之下,编译会被推迟到第一次执行这个函数,numba回去推断输入的参数类型,然后据此做出优化。如果第一次调用的时候传入的是整数,而后面某次传入的是复数,会再次编译生成不同的机器代码。

    2、Eager compilation

    这种方式是在定义函数的时候确定使用什么样的数据类型。

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

    这种做法是对编译器做出了fine-grained的控制。上面括号外面的int32指的是返回的数据类型,(int32,int32)指的是输入的参数类型。

    调用和内联其他函数:

    @jit
    def square(x):
        return x ** 2
    
    @jit
    def hypot(x, y):
        return math.sqrt(square(x) + square(y))

    注意上面hypot调用了square这个函数,@jit必须要添加在square这个函数上面,否则的话,会生成更慢的代码。

    @jit可以使用的数据类型:

    void: 空类型

    int8,uint8 ...16...32...64等

    intc, uintc 和 int, unsigned int是一样的

    intp, uintp是pointer-sized integers (没有搞懂)

    float32,float64

    complex64,complex128

    编译options:

    1、nopython:

    选择nopython模式或者是object模式

    2、nogil

    该项设置为true,一旦编译完成,就会释放GIL,这样的情况下就可以充分利用多核系统,但是需要注意多线程编程中需要注意的同步、一致性、竞争等情况。

    3、cache

    为了避免每次编译所耗费的时间,可以将函数编译完成的结果保存在一个file文件中。

    4、parallel

    自动并行化,注意需要和nopython=true一起使用

    @jit(nopython=True, parallel=True)
    def f(x, y):
        return x + y
  • 相关阅读:
    Spring 框架的概述以及Spring中基于XML的IOC配置
    SpringBoot(1)
    C/C++经典程序之打印三角形
    C++构造函数详解(复制构造函数)
    利用函数模板计算并返回数组d 中size个元素的平方和
    C++模板之typename和class关键字的区别
    构造函数与成员函数的区别?
    为什么多数穷人很难逆袭成功
    用递归方式求解这个问题:一只母兔从四岁开始每年生一只小母兔,按此规律,第n年有多少只母兔?
    编写一个函数 reverseDigit(int num).该函数读入一个整数,然后将这个整数的每个位上的数字逆序输出。
  • 原文地址:https://www.cnblogs.com/yanxingang/p/10910090.html
Copyright © 2011-2022 走看看