【实用小功能10】python运行加速神器——numba(详细教学版)

2023-10-18 04:28

本文主要是介绍【实用小功能10】python运行加速神器——numba(详细教学版),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

      • 1. 为什么python这么慢?
        • 1.1 动态变量
        • 1.2. 解释性语言
      • 2. Numba的介绍和使用
        • 2.1 numba加速python小实例
        • 2.2 个人经验
        • 2.3 其他

1. 为什么python这么慢?

python比c++慢,尤其是存在循环的情况下,python和c+的区别主要有:

1.1 动态变量

c++中需要对变量类型有严格的定义,比如int或者float类型。但是python不需要,它去掉了变量申明和数据类型。python是一种动态类型语言,它会在做运算的时候根据变量的值自动推断出其类型,这种动态类型的特性使得python编写更加简单和灵活,但同时增加了一定的时间开销,反观c/c++在运算时则只是简单的内存读写和机器指令(加减乘除…),所以c/c++的速度比python快很多。

1.2. 解释性语言

c/c++是编译型语言,需要先将源代码编译成机器码,然后再运行程序。

python是解释性语言,它的源代码是直接由解释器解释执行的,这意味着在编写python代码时,不需要先将代码编译成可执行文件,而是可以直接运行代码。所以python的执行速度相较于c/c++会慢很多。

这个问题的一种解决方法就是即时编译JIT(Just-in-time compilation)JIT编译器会动态地将高级语言编写的代码转换为机器码,可以直接由计算机的处理器执行,这是在运行时完成的,也就是代码执行之前,因此称为“即时”。JIT针对特定的硬件和操作系统进行代码优化,可以使得python代码获得显著的性能提升。

2. Numba的介绍和使用

github主页:https://github.com/numba/numba

在线文档:https://numba.readthedocs.io/en/stable/index.html

可直接pip/conda下载库

conda install numba
pip install numba

numba非常适合于使用了numpy数组、函数和循环的代码,使用的方法就是装饰器,用它!用的好时间节省个几十倍。numba的可使用范围:

  • 操作系统:Windows (64 bit), OSX, Linux (64 bit).
  • 架构:x86, x86_64, ppc64le, armv8l (aarch64), M1/Arm64.
  • GPU:Nvidia CUDA.
  • CPython
  • NumPy版本:1.22~1.25
2.1 numba加速python小实例
  • 使用python计算一个矩阵的所有元素的和

  • 原始代码

def cal_sum(a): result = 0 for i in range(a.shape[0]): for j in range(a.shape[1]): result += a[i, j] return result start = time.perf_counter()
a = np.random.random((5000, 5000)) 
result = cal_sum(a)
end = time.perf_counter()
print("原始代码耗时:{}s".format((end - start)))#OUT:
#原始代码耗时:5.725140199996531s
  • 使用numba加速
import numba@numba.jit(nopython=True) 
def cal_sum(a): result = 0 for i in range(a.shape[0]): for j in range(a.shape[1]): result += a[i, j] return result start = time.perf_counter()
a = np.random.random((5000, 5000)) 
result = cal_sum(a)
end = time.perf_counter()
print("加速后耗时:{}s".format((end - start)))#OUT:
#加速后耗时:0.2892118000017945s

@jit(nopython=True)@njit是等同的,这个选项指示numba在编译时尽可能地避免使用python对象,将python代码转换为更快的机器码,而不是使用python解释器来执行代码。

  • 多次调用同一个使用了numba加速的函数

numba在第首次调用函数的时候进行了编译,但当编译发生后,numba会将该函数的机器码进行缓存,如果再次调用该函数,它会直接从缓存中加载,而不需要再次编译。简而言之,在一段代码中的使用了numba的函数,第二次、第三次…调用该函数运算都要比第一次耗时更少

x = np.arange(100).reshape(10, 10)@jit(nopython=True)
def go_fast(a):trace = 0.0for i in range(a.shape[0]):trace += np.tanh(a[i, i])return a + tracestart = time.perf_counter()
go_fast(x)
end = time.perf_counter()
print("首次调用耗时:{}s".format((end - start)))start = time.perf_counter()
go_fast(x)
end = time.perf_counter()
print("再次调用耗时:{}s".format((end - start)))#OUT:
#首次调用耗时:0.16958359999989625s
#再次调用耗时:4.7599998652003706e-05s
  • 使用并行加速【失败,原因还未知】

官方使用说明网址:numba-parallel

拿了官方的代码对比了下未使用并行和使用并行的,但是并行的反而更慢,没仔细细究缘由。

from numba import njit@njit()
def prange_test(A):s = 0for i in range(A.shape[0]):s += A[i]return sstart = time.perf_counter()
a = np.arange(1000)
result = prange_test(a)
end = time.perf_counter()
print("无并行耗时:{}s".format((end - start)))#OUT:
#无并行耗时:0.07213479999336414s
from numba import njit, prange@njit(parallel=True)
def prange_test(A):s = 0# Without "parallel=True" in the jit-decorator# the prange statement is equivalent to rangefor i in prange(A.shape[0]):s += A[i]return sstart = time.perf_counter()
a = np.arange(1000)
result = prange_test(a)
end = time.perf_counter()
print("并行耗时:{}s".format((end - start)))#OUT:
#并行耗时:0.36391139999614097s
2.2 个人经验

上面的函数比较简单,但是在实际使用中我们的函数可能复杂很多,简单地直接在函数上添加一个装饰器会出现各种报错,我们需要针对问题调整函数代码,大概陈列几个我遇到的问题及解决的方法。

  • 报错1
TypingError: Failed in nopython mode pipeline (step: nopython frontend)
Cannot infer the type of variable 'result', have imprecise type: list(undefined)<iv=None>. For Numba to be able to compile a list, the list must have a known and
precise type that can be inferred from the other variables. Whilst sometimes
the type of empty lists can be inferred, this is not always the case, see this
documentation for help:https://numba.pydata.org/numba-doc/latest/user/troubleshoot.html#my-code-has-an-untyped-list-problem

有些报错,会给个网址告诉你报错原因,点进去认真看下然后照着意思修改修改自己的代码就行了,但这个问题的解决方法如下:

@numba.jit(nopython=True) 
def test(): result, result1 = [], 0return result, result1test()# 改为
@numba.jit(nopython=True) 
def test(): result = []result1 = 0return result, result1test()
  • 报错2:
TypingError: Failed in nopython mode pipeline (step: nopython frontend)
Unknown attribute 'tolist' of type array(float32, 1d, C)...
Untyped global name 'input': Cannot determine Numba type of <class 'method'>

这样的问题是因为numba现在还有一些函数是不支持,比如上面python自带的input()函数和数组的tolist()函数,遇到这些问题的时候解决方法就是使用同样功能的且numba支持的函数or自己重写一个函数。

  • 报错3
def test_func():return True@jit(nopython=True)
def test(): flag = test_func()test()
TypingError: Failed in nopython mode pipeline (step: nopython frontend)
Untyped global name 'test_func': Cannot determine Numba type of <class 'function'>

这个问题是numba不支持函数中嵌套自己的函数,解决方法就是把调用的函数合并到一个函数中。

  • 报错4

会有一些与list列表相关的报错,numba貌似很不支持列表操作,尤其是嵌套列表类似[[[1,2],[2,3]],[[2,2],[8,3]]],解决方法是将这种列表改为数组进行操作。

2.3 其他

numba还提供了很多其他加速方法(我还没试):

  • 想节省编译时间,numba提供了提前编译模式:Ahead-of-Time compilation
  • 使用GPU:cuda-index

参考:Python 提速大杀器之 numba 篇

这篇关于【实用小功能10】python运行加速神器——numba(详细教学版)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/230158

相关文章

python panda库从基础到高级操作分析

《pythonpanda库从基础到高级操作分析》本文介绍了Pandas库的核心功能,包括处理结构化数据的Series和DataFrame数据结构,数据读取、清洗、分组聚合、合并、时间序列分析及大数据... 目录1. Pandas 概述2. 基本操作:数据读取与查看3. 索引操作:精准定位数据4. Group

Python pandas库自学超详细教程

《Pythonpandas库自学超详细教程》文章介绍了Pandas库的基本功能、安装方法及核心操作,涵盖数据导入(CSV/Excel等)、数据结构(Series、DataFrame)、数据清洗、转换... 目录一、什么是Pandas库(1)、Pandas 应用(2)、Pandas 功能(3)、数据结构二、安

Python使用Tenacity一行代码实现自动重试详解

《Python使用Tenacity一行代码实现自动重试详解》tenacity是一个专为Python设计的通用重试库,它的核心理念就是用简单、清晰的方式,为任何可能失败的操作添加重试能力,下面我们就来看... 目录一切始于一个简单的 API 调用Tenacity 入门:一行代码实现优雅重试精细控制:让重试按我

深度解析Spring Security 中的 SecurityFilterChain核心功能

《深度解析SpringSecurity中的SecurityFilterChain核心功能》SecurityFilterChain通过组件化配置、类型安全路径匹配、多链协同三大特性,重构了Spri... 目录Spring Security 中的SecurityFilterChain深度解析一、Security

Python安装Pandas库的两种方法

《Python安装Pandas库的两种方法》本文介绍了三种安装PythonPandas库的方法,通过cmd命令行安装并解决版本冲突,手动下载whl文件安装,更换国内镜像源加速下载,最后建议用pipli... 目录方法一:cmd命令行执行pip install pandas方法二:找到pandas下载库,然后

Apache Ignite 与 Spring Boot 集成详细指南

《ApacheIgnite与SpringBoot集成详细指南》ApacheIgnite官方指南详解如何通过SpringBootStarter扩展实现自动配置,支持厚/轻客户端模式,简化Ign... 目录 一、背景:为什么需要这个集成? 二、两种集成方式(对应两种客户端模型) 三、方式一:自动配置 Thick

Python实现网格交易策略的过程

《Python实现网格交易策略的过程》本文讲解Python网格交易策略,利用ccxt获取加密货币数据及backtrader回测,通过设定网格节点,低买高卖获利,适合震荡行情,下面跟我一起看看我们的第一... 网格交易是一种经典的量化交易策略,其核心思想是在价格上下预设多个“网格”,当价格触发特定网格时执行买

Python标准库之数据压缩和存档的应用详解

《Python标准库之数据压缩和存档的应用详解》在数据处理与存储领域,压缩和存档是提升效率的关键技术,Python标准库提供了一套完整的工具链,下面小编就来和大家简单介绍一下吧... 目录一、核心模块架构与设计哲学二、关键模块深度解析1.tarfile:专业级归档工具2.zipfile:跨平台归档首选3.

使用Python构建智能BAT文件生成器的完美解决方案

《使用Python构建智能BAT文件生成器的完美解决方案》这篇文章主要为大家详细介绍了如何使用wxPython构建一个智能的BAT文件生成器,它不仅能够为Python脚本生成启动脚本,还提供了完整的文... 目录引言运行效果图项目背景与需求分析核心需求技术选型核心功能实现1. 数据库设计2. 界面布局设计3

Python进行JSON和Excel文件转换处理指南

《Python进行JSON和Excel文件转换处理指南》在数据交换与系统集成中,JSON与Excel是两种极为常见的数据格式,本文将介绍如何使用Python实现将JSON转换为格式化的Excel文件,... 目录将 jsON 导入为格式化 Excel将 Excel 导出为结构化 JSON处理嵌套 JSON: