Numba:加速python代码

news2025/1/10 20:32:56

 通常我们加速python代码是考虑把.py文件编译成.c文件,然后把.c文件编译成.so或.pyd文件,可以参考另一章博文:

Cython为py程序加密&提高性能_cythonize_Rnan-prince的博客-CSDN博客

现在我们考虑一种不用将py文件编译成.c文件的方法:numba,其实原理差不多,只是用户不感知。

Numba简介

Numba是一款可以将python函数编译为机器代码的JIT编译器,经过Numba编译的python代码(仅限数组运算),其运行速度可以接近C或FORTRAN语言。普通python语言靠Cython编译的,但是Numba使用Jit编译器可以直接将一个函数转化为机器码。

User Manual — Numba 0.50.1 documentationicon-default.png?t=N7T8http://numba.pydata.org/numba-doc/latest/user/index.htmlJIT的全称是 Just-in-time,在 numba 里面则特指 Just-in-time compilation(即时编译)。

编译方式有:

  • 动态编译(dynamic compilation):指的是“在运行时进行编译”;与之相对的是事前编译(ahead-of-time compilation,简称AOT),也叫静态编译(static compilation)。
  • JIT编译(just-in-time compilation)狭义来说是当某段代码即将第一次被执行时进行编译,因而叫“即时编译”。JIT编译是动态编译的一种特例。JIT编译一词后来被泛化,时常与动态编译等价;但要注意广义与狭义的JIT编译所指的区别。
  • 自适应动态编译(adaptive dynamic compilation)也是一种动态编译,但它通常执行的时机比JIT编译迟,先让程序“以某种方式”先运行起来,收集一些信息之后再做动态编译。这样的编译可以更加优化。

Numba 的最基础应用就是加速 Python 中的循环操作。

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

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

jit装饰器

numba加速,针对数字运算,所以输入输出为数组格式

jit和njit的使用,要不要加(),括号有没有一样不一样

@jit() 里面可以增加参数,不添加参数设置时和jit一样

import jit
@numba.jit
def func(x,y):
    s = 1 
    for i in range(x, y):
        c *= i
    return c

上面这段代码是numba.jit的简单应用,在函数第一次执行的时候,numba推断出参数类型,然后基于这个信息生产优化后的代码。

指定签名

import numba 
@numba.jit(int32(int32, int32))
def func(x,y):
    s = 1 
    for i in range(x, y):
        c *= i
    return c

@numba.jit括号内的是指定签名,编译器将控制类型选择,并不允许其他类型的参数输入,这会带来速度上的优势。

常用的数据类型有:

  • int8, uint8, int16, uint16, int32, uint32, int64,uint64,各种长度整数。图像处理中unit8很常用。
  • float32 ,float64, 单精度浮点数,双精度浮点数
  • complex64 ,complex128, 单精度复数,双精度复数
  • void, 对应python中返回Nothing。
  • intc and uintc 等效于C中的 int 和uint
  • 各种数组类型,如float32[:]表示一维单精度浮点数组,uint8[:,:] 表示二维无符号8位整数数组(常用于图像数组)
  • 元组, 如nb.types.UniTuple(nb.float32, 3) 表示3个元素的元组,元素的类型是float32

重要参数 

编译模式(nopython模式和object模式)

nopython和object是numba的两种编译模式,前者编译的代码更快,但是可能会因为某些限制但是退化为object, 通过nopython=True可以阻止退化并抛出异常。

@njit() 是jit(nopython=True)的默认,@numba.njit与@numba.jit(nopython=True)等价。里面也可以增加设置,比如parallel=True,和prange的使用 只能对数字运算进行加速,建议使用njit,使用起来更加灵活一些

import jit
@numba.njit
def func(x,y):
    s = 1 
    for i in range(x, y):
        c *= i
    return c

nogil

当Numba不需要保持全局线程锁GIL时,可以设定nogil=True,当进入这类编译好的函数时,Numba将会释放全局线程锁。这样可以利用多核系统,但不能使用的函数是在object模式下编译。

@numba.jit(nogil=True)
def func(x,y):
    s = 1 
    for i in range(x, y):
        c *= i
    return c

 cache

想要避免你调用python程序的编译时间,可以通过cache=True来指定numba保存函数编译结果到一个基于文件的缓存中。

@numba.jit(cache=True)
def func(x,y):
    s = 1 
    for i in range(x, y):
        c *= i
    return c

parallel

parallel=True将函数中的操作自动并行化,必须要和nopython=True配合起来一起使用。在定义函数内部,有可并行且不会每次并行之间不会相互影响时使用。编译器将编译一个版本,并行运行多个原生的线程(没有GIL)。简单的for循环的话开启的效果就会比较明显。

@numba.jit(nopython=True, parallel=True)
def func(x,y):
    s = 1 
    for i in numba.prange(x, y):
        c *= i
    return c

boundchecks

什么时候应该 boundchecks 关闭

boundscheck: bool Set to True to enable bounds checking for array indices. Out of bounds accesses will raise IndexError. The default is to not do bounds checking. If bounds checking is disabled, out of bounds accesses can produce garbage results or segfaults. However, enabling bounds checking will slow down typical functions, so it is recommended to only use this flag for debugging. You can also set the NUMBA_BOUNDSCHECK environment variable to 0 or 1 to globally override this flag.

检查数组索引是否不对劲,但是费时间,在保证对的情况下可以设置为False

@numba.njit(boundcheck=False)
def func(x,y):
    s = 1 
    for i in range(x, y):
        c *= i
    return c

常见错误

Numba函数参数类型不匹配定义ListType[数组(float64,2d,C)]错误

类型在Numba官方网站上也找不到。让一个基于numba.typeof()返回的解析器函数能够创建装饰器的字符串也是非常有帮助的。注意:运行一定要将@njit(int32(int32))注释掉,否则报错

import numba
from numba import njit, int32


# @njit(int32(int32))
def func(a):
    print(numba.typeof(a))
    return a


func(3)
print(func.inspect_types())

 还有一个超级有用的行来获取numba函数的类型签名:func.inspect_types()

为什么python这么慢?numba解决了什么问题? 

这个大神讲的非常好:

为什么python这么慢?numba解决了什么问题? - 知乎


参考:

【深度好文】Python加速库Numba简介

python numba教程_Numba 开发手册(一)_不设目标的博客-CSDN博客

Numba函数参数类型不匹配定义ListType[数组(float64,2d,C)]错误-腾讯云开发者社区-腾讯云

利用numba給Python代码加速 [1]-腾讯云开发者社区-腾讯云

Numba CPU 并行 - 知乎 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1002808.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

正中优配:月线macd指标参数设置?

随着投资者长期持有股票的越来越受欢迎,月线MACD目标已成为识别趋势和交易信号的重要东西。但是,许多投资者在设置MACD目标参数时仍然感到困惑。本文将从多个视点剖析,为您解答月线MACD目标参数设置的问题。 什么是MACD目标? MAC…

630. 课程表 III

文章目录 Tag题目来源题目解读解题思路方法一:贪心优先队列 写在最后 Tag 【贪心】【优先队列】【数组】 题目来源 630. 课程表 III 题目解读 有 n 门编号从 1 到 n 的课程,有一个数组 courses,其中 courses[i] [duration, lastDay] 表示…

喜报 | 祝贺璞华科技通过CMMI Lv5 等级复审!

喜报频传 璞华科技顺利通过复审认证 再次荣获CMMI5级证书 让我们共同庆祝这一荣耀的时刻 展望更加美好的未来 2023年8月,经Safety Equipment Institute评估,璞华科技顺利通过全球软件领域CMMI五级(简称CMMI5)复审认证&#xf…

【Vue】vue2使用pdfjs预览pdf文件,在线预览方式一,pdfjs文件包打开新窗口预览pdf文件

系列文章目录 【Vue】vue2预览显示quill富文本内容,vue-quill-editor回显页面,v-html回显富文本内容 【Vue】vue2项目使用swiper轮播图2023年8月21日实战保姆级教程 【Vue】vue2使用pdfjs预览pdf文件,在线预览方式一,pdfjs文件包…

ES中type和keyword两个数据类型的区别

前言 这是我在这个网站整理的笔记,关注我,接下来还会持续更新。 作者:神的孩子都在歌唱 参考文章: https://segmentfault.com/q/1010000017312707 ES数据类型:type与keyword:https://blog.csdn.net/ywb201…

COMPUTATIONAL BIOLOGYAND BIOIINFORMATICS投稿经验分享

IEEE/ACM Transactions on Computational Biology and Bioinformatics 关于latex,用模板选择:IEEE模板选择器,进行选择就行。 注意页数!超了加钱! 1)注册登录,进入之后开始投稿。(这里也可以看到页数限制信息)按顺序添加标题和摘要。 2) 先上上传pdf文件,然后上传其…

荧光灯和led灯哪个对眼睛好?分享专业的护眼台灯

发现有很多家庭都忽略了孩子学习时光线的的重要性,经常是开着家里的顶灯给孩子写作业,但其实如果光线不适合或者不够充足,对孩子眼睛的危害是很大的。也有些家长会选择给孩子挑选台灯,不过并不知道哪种好,例如最近我看…

芯科蓝牙BG27开发笔记4-SSV5 IDE的使用

1. 如何转移工作区的项目文件到新的文件夹,并且可以继续使用ssv5编辑、编译? 从默认的工作区将目标工程整体拷贝出来 目标文件夹: 进入ssv5点击导入工程,并选择目标文件夹 继续下一步,修改项目文件夹所在位置为其源码…

北京青年与中青年人群消费模型调研

本项目旨在研究北京青年(27岁及以下)人群与中青年人群(28岁以上)的消费模型的不同以及其背后可能的原因。在此之前,我们通过国家统计局北京的官方数据(如下图),确定了普通人大致在哪…

SpringBoot自动装配源码解析

Spirngboot为啥会比Spring使用更简单,少了那么多的Xml文件?一切都是基于SpringBoot的自动装配,当然SpringBoot的自动装配也是一个高频的面试题。 1.SpringApplication注解的源码分析 在分析源码时,都要问一问为什么SpringBoot能…

时间序列论文-聚类和异常检测(一)

这篇文章摘自,知乎:https://www.zhihu.com/question/29507442/answer/1212624591?utm_id0 写的很好,就记录一下。 两篇关于时间序列的论文 原文链接:两篇关于时间序列的论文 这次整理的就是清华大学裴丹教授所著的两篇与时间序…

Qt/C++音视频开发52-采集本地屏幕桌面的终极设计

一、前言 最开始设计的时候,只考虑了一个屏幕的情况,这种当然是最理想的情况,实际上双屏或者多屏的用户也不在少数,比如我这两个屏幕,屏幕1是1080P,屏幕2是2K分辨率,打印两个屏幕的区域是 QRec…

【EI会议征稿】2023年智能科学与计算机工程国际学术会议(ISCE 2023)

2023年智能科学与计算机工程国际学术会议(ISCE 2023) 2023 International Conference on Intelligence Scicence andComputer Engineering 2023年11月3-5日 中国-西双版纳 迄今为止,人工智能研究在一些特殊领域取得了一定的实质性进展。然…

单相并联下垂控原理

Part1 上述有个核心的piont是等效阻抗上的电压一般时很小的,这就导致逆变器输出电压矢量E和负载电压矢量UL之间的夹角很小 》基于上述的结论有助于我们去简化下垂控制的公式!!! Part2 上述得到负载电流,接着乘以负载…

计算机算法分析与设计(1)---求算法时间复杂性(手写例题)

文章目录 一、主定理求解二、递归树求解三、递归树求解含O的递归方程 一、主定理求解 二、递归树求解 三、递归树求解含O的递归方程

后端|一个分布式锁「失效」的案例分析

小猿最近很苦恼:明明加了分布式锁,为什么并发还是会出问题呢? 故事从接到需求开始说起。 接到需求 小猿前一阵接到一个小任务,里面有一个功能对应的场景如下: 封装一个对账户余额进行加减操作的方法;所属服…

shell指令,通过函数实现数组求和,通过函数获取用户uid和gid

一、实现一个对数组求和的函数&#xff0c;数组通过实参传递给函数 num0 read -p "请输入一组数据&#xff1a;" -a arr function add() {for ((i0; i<${#arr[*]}; i))do ((numarr[i]))donereturn $num } add ${arr[*]} echo $? 二、写一个函数&#xff0c;输出…

基于STM32智能环境系统

摘要 本系统采用stm32f407作为主控芯片&#xff0c;实现对环境的监测。并且通过和手机通信&#xff0c;获取当前的天气预报信息&#xff0c;结合当前测得的温湿度&#xff0c;可以为用户提供出行建议。利用stm32自带的RTC可以实现时间及闹钟功能。此外RTC还可以用于电子日历的…

《信息系统项目管理师教程(第4版)》第19章 配置与变更管理 知识点整理 xmind思维导图

已上传xmind思维导图&#xff0c;需要可下载 一、配置管理 基于配置库的变更控制(经常考) 二、变更管理

华为OD七日集训第4期 - 按算法分类,由易到难,循序渐进,玩转OD

目录 一、适合人群二、本期训练时间三、如何参加四、7日集训第4期五、精心挑选21道高频100分经典题目&#xff0c;作为入门。第1天、数据结构第2天、滑动窗口第3天、贪心算法第4天、二分查找第5天、分治递归第6天、深度优先搜索dfs算法第7天、宽度优选算法&#xff0c;回溯法 六…