Python中Numba库装饰器的具体使用

 更新时间:2024年01月28日 16:27:46   作者:知识在于积累  
Numba是一个针对Python的开源JIT编译器,使用Numba非常方便,只需要在Python原生函数上增加一个装饰器,本文主要介绍了Python中Numba库装饰器的具体使用,感兴趣的可以了解一下

一、运行速度是Python天生的短板

在这里插入图片描述

1.1 编译型语言:C++

对于编译型语言,开发完成以后需要将所有的源代码都转换成可执行程序,比如 Windows 下的.exe文件,可执行程序里面包含的就是机器码。只要我们拥有可执行程序,就可以随时运行,不用再重新编译了,也就是“一次编译,无限次运行”。
在运行的时候,我们只需要编译生成的可执行程序,不再需要源代码和编译器了,所以说编译型语言可以脱离开发环境运行。
编译型语言一般是不能跨平台的,也就是不能在不同的操作系统之间随意切换。

1.2 解释型语言:Python

对于解释型语言,每次执行程序都需要一边转换一边执行,用到哪些源代码就将哪些源代码转换成机器码,用不到的不进行任何处理。每次执行程序时可能使用不同的功能,这个时候需要转换的源代码也不一样。
因为每次执行程序都需要重新转换源代码,所以解释型语言的执行效率天生就低于编译型语言,甚至存在数量级的差距。计算机的一些底层功能,或者关键算法,一般都使用 C/C++ 实现,只有在应用层面(比如网站开发、批处理、小工具等)才会使用解释型语言。
在运行解释型语言的时候,我们始终都需要源代码和解释器,所以说它无法脱离开发环境。

1.3 速度对比:C++比Python快25倍

我不会C++语言、也没有C++语言的运行的环境,借用网友的对比结果:

在这里插入图片描述

编译后,运行C++代码,生成全部13-mers共6700万个大约需要2.42秒。这意味着运行相同算法,Python用时是C++的25倍多。

二、Numba使用与否的对比,计算1000万以内的素数

2.1 原生Python,计算1000万以内的素数

def U27_1000W以内的素数():
    import math
    import time

    def is_prime(num):
        if num == 2:
            return True
        if num <= 1 or num % 2 == 0:
            return False
        for div in range(3, int(math.sqrt(num) + 1), 2):
            if num % div == 0:
                return False
        return True

    def run_program(N):
        total = 0
        for i in range(N):
            if is_prime(i):
                total += 1
        return total

    # if __name__ == "__main__":
    N = 10000000
    start = time.time()
    total = run_program(N)
    end = time.time()
    print(f"1000万以内所有的素数有 {total} 个")
    print(f"纯Python耗时: {end - start} 秒\b")
    return end - start

2.2 Numba装饰器,计算1000万以内的素数

def U28_1000W以内的素数_Numba装饰器():
    import math
    import time
    from numba import njit, prange

    # @njit 相当于 @jit(nopython=True) 
    @njit
    def is_prime(num):
        if num == 2:        # 2为素数
            return True
        if num <= 1 or num % 2 == 0:     # 偶数中除了2都不是素数
            return False
        for div in range(3, int(math.sqrt(num) + 1), 2):
            if num % div == 0:
                return False
        return True

    #使用Numba的prange来进行并发循环计算
    @njit(parallel = True)
    def run_program(N):
        total = 0
        #使用Numba提供的prange参数来进行并行计算
        for i in prange(N):
            if is_prime(i):
                total += 1
        return total

    # if __name__ == "__main__":
    N = 10000000
    start = time.time()
    total = run_program(N)
    end = time.time()
    print(f"1000万以内所有的素数有 {total} 个")
    print(f"Numba装饰器耗时: {end - start} 秒\b")
    return end - start

2.3 实测速度:使用numba装饰器,速度提升 22.0 倍,逼近C++

t0 = U27_1000W以内的素数()
t1 = U28_1000W以内的素数_Numba装饰器()
print(f'使用numba装饰器,速度提升 {round(t0/t1, 0)} 倍')


1000万以内所有的素数有 664579 个
纯Python耗时: 86.78110885620117 秒
1000万以内所有的素数有 664579 个
Numba装饰器耗时: 3.9410934448242188 秒
使用numba装饰器,速度提升 22.0 倍

三、素数算法

质数也就是大于1的整数中,除了1和它本身以外不能被其他整数整除的数,也叫素数。

# 算法一:针对输入的数字x,我们可以遍历从2到x-1这个区间中的数,如果x能被这个区间中任意一个数整除,那么它就不是质数。
def is_prime1(x):
    for i in range(2, x):
        if x % i == 0:
            return False
    return True

# 算法二:对算法一的优化,事实上只需要遍历从2到√x即可。
def is_prime2(x):
    for i in range(2, int(x ** 0.5) + 1):
        if x % i == 0:
            return False
    return True

# 算法三:偶数中除了2都不是质数,且奇数的因数也没有偶数,因此可以进一步优化。
def is_prime3(x):
    if x == 2:
        return True
    elif x % 2 == 0:
        return False
    for i in range(3, int(x ** 0.5) + 1, 2):
        if x % i == 0:
            return False
    return True

# 算法四:任何一个自然数,总可以表示成以下六种形式之一:6n,6n+1,6n+2,6n+3,6n+4,6n+5(n=0,1,2...)我们可以发现,除了2和3,只有形如6n+1和6n+5的数有可能是质数。且形如6n+1和6n+5的数如果不是质数,它们的因数也会含有形如6n+1或者6n+5的数,因此可以得到如下算法:
def is_prime4(x):
    if (x == 2) or (x == 3):
        return True
    if (x % 6 != 1) and (x % 6 != 5):
        return False
    for i in range(5, int(x ** 0.5) + 1, 6):
        if (x % i == 0) or (x % (i + 2) == 0):
            return False
    return True

四、Numba

4.1 官方文档

numba 是一款可以将 python 函数编译为机器代码的JIT编译器,经过 numba 编译的python 代码(仅限数组运算),其运行速度可以接近 C 或 FORTRAN 语言。
官方文档链接:http://numba.pydata.org/numba-doc/latest/index.html

到此这篇关于Python中Numba库装饰器的具体使用的文章就介绍到这了,更多相关Python Numba库装饰器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Python实现文件复制删除

    Python实现文件复制删除

    本文通过2个具体的实例,给大家展示了如何使用Python实现文件的复制与删除,非常的简单实用,有需要的小伙伴可以参考下
    2016-04-04
  • 正确的使用Python临时文件

    正确的使用Python临时文件

    这篇文章主要介绍了正确的使用Python临时文件,帮助大家更好的理解和学习使用python,感兴趣的朋友可以了解下
    2021-03-03
  • Python线程之如何解决共享变量问题

    Python线程之如何解决共享变量问题

    这篇文章主要介绍了Python线程之如何解决共享变量问题,掐灭问我们学习了银行转账的这个场景,本文解决上次多个线程的操作都更改了amount变量导致运行结果不对的问题,需要的朋友可以参考一下
    2022-02-02
  • Python3二分查找库函数bisect(),bisect_left()和bisect_right()的区别

    Python3二分查找库函数bisect(),bisect_left()和bisect_right()的区别

    这篇文章主要介绍了Python3二分查找库函数bisect(),bisect_left()和bisect_right()的区别,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-03-03
  • 使用python进行量化交易的完整指南

    使用python进行量化交易的完整指南

    量化交易,作为现代金融市场中的一种先进交易方式,通过运用数学模型、统计方法和计算机算法来指导交易决策,旨在提高交易效率和决策的准确性,本文将详细介绍如何使用Python进行量化交易,包括策略开发、数据处理、回测、风险管理和实盘交易等关键步骤
    2024-09-09
  • Python列表生成式与生成器操作示例

    Python列表生成式与生成器操作示例

    这篇文章主要介绍了Python列表生成式与生成器操作,结合实例形式分析了Python列表生成式与生成器的功能、使用方法及相关操作技巧,需要的朋友可以参考下
    2018-08-08
  • Python 多模式字符串搜索 Aho-Corasick详解

    Python 多模式字符串搜索 Aho-Corasick详解

    Aho-Corasick 算法是一种用于精确或近似多模式字符串搜索的高效算法,本文给大家介绍Python 多模式字符串搜索 Aho-Corasick的相关知识,感兴趣的朋友跟随小编一起看看吧
    2025-01-01
  • 分分钟入门python语言

    分分钟入门python语言

    分分钟学会一门语言之Python篇,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-03-03
  • 关于python通过新建环境安装tfx的问题

    关于python通过新建环境安装tfx的问题

    这篇文章主要介绍了python安装tfx/新建环境,新建一个环境tfx专门用来运行流水线,这个环境安装python3.8,对python安装tfx相关知识感兴趣的朋友一起看看吧
    2022-05-05
  • Python实用技巧之轻松处理大型文件

    Python实用技巧之轻松处理大型文件

    Python在文件处理方面提供了非常强大的支持,然而,当处理大型文件时,标准的文件处理技术会导致高内存使用,所以下面我们就来看看如何在Python中有效地处理大型文件吧
    2024-03-03

最新评论