網(wǎng)站首頁 編程語言 正文
前言;
python由于它動(dòng)態(tài)解釋性語言的特性,跑起代碼來相比java、c++要慢很多,尤其在做科學(xué)計(jì)算的時(shí)候,十億百億級(jí)別的運(yùn)算,讓python的這種劣勢更加凸顯。
辦法永遠(yuǎn)比困難多,numba就是解決python慢的一大利器,可以讓python的運(yùn)行速度提升上百倍!
一、什么是numba?
numba是一款可以將python函數(shù)編譯為機(jī)器代碼的JIT編譯器,經(jīng)過numba編譯的python代碼(僅限數(shù)組運(yùn)算),其運(yùn)行速度可以接近C或FORTRAN語言。
python之所以慢,是因?yàn)樗强緾Python編譯的,numba的作用是給python換一種編譯器。
python、c、numba三種編譯器速度對(duì)比:
使用numba非常簡單,只需要將numba裝飾器應(yīng)用到python函數(shù)中,無需改動(dòng)原本的python代碼,numba會(huì)自動(dòng)完成剩余的工作。
import numpy as np import numba from numba import jit @jit(nopython=True) # jit,numba裝飾器中的一種 def go_fast(a): # 首次調(diào)用時(shí),函數(shù)被編譯為機(jī)器代碼 ? ? trace = 0 ? ? # 假設(shè)輸入變量是numpy數(shù)組 ? ? for i in range(a.shape[0]): ? # Numba 擅長處理循環(huán) ? ? ? ? trace += np.tanh(a[i, i])? ? ? return a + trace
以上代碼是一個(gè)python函數(shù),用以計(jì)算numpy
數(shù)組各個(gè)數(shù)值的雙曲正切值,我們使用了numba裝飾器,它將這個(gè)python函數(shù)編譯為等效的機(jī)器代碼,可以大大減少運(yùn)行時(shí)間。
二、numba適合科學(xué)計(jì)算
numpy是為面向numpy數(shù)組的計(jì)算任務(wù)而設(shè)計(jì)的。
在面向數(shù)組的計(jì)算任務(wù)中,數(shù)據(jù)并行性對(duì)于像GPU這樣的加速器是很自然的。Numba了解NumPy數(shù)組類型,并使用它們生成高效的編譯代碼,用于在GPU或多核CPU上執(zhí)行。特殊裝飾器還可以創(chuàng)建函數(shù),像numpy函數(shù)那樣在numpy數(shù)組上廣播。
什么情況下使用numba呢?
- 使用numpy數(shù)組做大量科學(xué)計(jì)算時(shí)
- 使用for循環(huán)時(shí)
三、學(xué)習(xí)使用numba
第一步:導(dǎo)入numpy、numba及其編譯器
import numpy as np import numba? from numba import jit
第二步:傳入numba裝飾器jit,編寫函數(shù)
# 傳入jit,numba裝飾器中的一種 @jit(nopython=True)? def go_fast(a): # 首次調(diào)用時(shí),函數(shù)被編譯為機(jī)器代碼 ? ? trace = 0 ? ? # 假設(shè)輸入變量是numpy數(shù)組 ? ? for i in range(a.shape[0]): ? # Numba 擅長處理循環(huán) ? ? ? ? trace += np.tanh(a[i, i]) ?# numba喜歡numpy函數(shù) ? ? return a + trace # numba喜歡numpy廣播
nopython = True選項(xiàng)要求完全編譯該函數(shù)(以便完全刪除Python解釋器調(diào)用),否則會(huì)引發(fā)異常。這些異常通常表示函數(shù)中需要修改的位置,以實(shí)現(xiàn)優(yōu)于Python的性能。強(qiáng)烈建議您始終使用nopython = True。
第三步:給函數(shù)傳遞實(shí)參
# 因?yàn)楹瘮?shù)要求傳入的參數(shù)是nunpy數(shù)組 x = np.arange(100).reshape(10, 10)? # 執(zhí)行函數(shù) go_fast(x)
第四步:經(jīng)numba加速的函數(shù)執(zhí)行時(shí)間
% timeit go_fast(x)
輸出:
3.63 μs ± 156 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
第五步:不經(jīng)numba加速的函數(shù)執(zhí)行時(shí)間
def go_fast(a): # 首次調(diào)用時(shí),函數(shù)被編譯為機(jī)器代碼 ? ? trace = 0 ? ? # 假設(shè)輸入變量是numpy數(shù)組 ? ? for i in range(a.shape[0]): ? # Numba 擅長處理循環(huán) ? ? ? ? trace += np.tanh(a[i, i]) ?# numba喜歡numpy函數(shù) ? ? return a + trace # numba喜歡numpy廣播 x = np.arange(100).reshape(10, 10)? %timeit go_fast(x)
輸出:
136 μs ± 1.09 μs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
結(jié)論:
在numba加速下,代碼執(zhí)行時(shí)間為3.63微秒/循環(huán)。不經(jīng)過numba加速,代碼執(zhí)行時(shí)間為136微秒/循環(huán),兩者相比,前者快了40倍。
四、numba讓python飛起來
前面已經(jīng)對(duì)比了numba
使用前后,python代碼速度提升了40倍,但這還不是最快的。
這次,我們不使用numpy數(shù)組,僅用for循環(huán),看看nunba對(duì)for循環(huán)到底有多鐘愛!
# 不使用numba的情況 def t(): ? ? x = 0 ? ? for i in np.arange(5000): ? ? ? ? x += i ? ? return x %timeit(t())
輸出:
408 μs ± 9.73 μs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
# 使用numba的情況 @jit(nopython=True)? def t(): ? ? x = 0 ? ? for i in np.arange(5000): ? ? ? ? x += i ? ? return x %timeit(t())?
輸出:
1.57 μs ± 53.8 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
使用numba前后分別是408微秒/循環(huán)、1.57微秒/循環(huán),速度整整提升了200多倍!
結(jié)語:
numba對(duì)python代碼運(yùn)行速度有巨大的提升,這極大的促進(jìn)了大數(shù)據(jù)時(shí)代的python數(shù)據(jù)分析能力,對(duì)數(shù)據(jù)科學(xué)工作者來說,這真是一個(gè)lucky tool !
當(dāng)然numba不會(huì)對(duì)numpy和for循環(huán)以外的python代碼有很大幫助,你不要指望numba可以幫你加快從數(shù)據(jù)庫取數(shù),這點(diǎn)它真的做不到哈。
原文鏈接:https://zhuanlan.zhihu.com/p/78882641
相關(guān)推薦
- 2022-10-06 Go語言實(shí)現(xiàn)常用排序算法的示例代碼_Golang
- 2022-04-20 用Python實(shí)現(xiàn)插值算法_python
- 2022-09-17 C++?如何實(shí)現(xiàn)順序棧(使用模板類)_C 語言
- 2022-10-31 Python3邏輯運(yùn)算符與成員運(yùn)算符_python
- 2022-07-03 C#列表List<T>、HashSet和只讀集合介紹_C#教程
- 2022-09-09 如何通過pycharm實(shí)現(xiàn)對(duì)數(shù)據(jù)庫的查詢等操作(非多步操作)_python
- 2023-02-25 Redisson如何解決redis分布式鎖過期時(shí)間到了業(yè)務(wù)沒執(zhí)行完問題_Redis
- 2022-08-16 python+pytest接口自動(dòng)化參數(shù)關(guān)聯(lián)_python
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支