当前位置: 首页 > 后端技术 > Python

numba,让python快一百倍

时间:2023-03-25 22:05:31 Python

python,由于其动态解释语言的特性,运行代码比java和c++慢很多,尤其是在做科学计算的时候,几十亿上百亿的运算,让python的这个缺点是更加突出。解决办法总是比困难多,而numba是解决python慢??的利器,可以将python的运行速度提高数百倍!什么是麻麻?numba是一个JIT编译器,可以将python函数编译成机器码。numba编译出来的python代码(只针对数组操作)可以以接近C或FORTRAN的速度运行。python之所以慢,是因为它是用CPython编译的。numba的作用是给python换一个编译器。numba的使用非常简单,只需要在python函数上应用numba装饰器,无需改动原有的python代码,numba会自动完成剩下的工作。importnumbafromnumbaimportjit@jit(nopython=True)#jit,numba装饰器之一defgo_fast(a):#第一次调用时,函数被编译为机器代码trace=0#假设输入变量是一个numpyarrayforiinrange(a.shape[0]):#Numba擅长处理循环trace+=np.tanh(a[i,i])returna+trace上面代码是python函数计算值numpy数组的每个值的双曲正切,我们使用了numba装饰器,它将这个python函数编译为等效的机器代码,可以大大减少运行时间。numba适用于科学计算numpy专为面向numpy数组的计算任务而设计。在面向数组的计算任务中,数据并行对于GPU等加速器来说是很自然的。Numba理解NumPy数组类型并使用它们生成高效的编译代码以在GPU或多核CPU上执行。特殊装饰器还可以创建像numpy函数一样在numpy数组上广播的函数。什么情况下使用numba?使用numpy数组做大量科学计算时,使用for循环,学习使用numba第一步:导入numpy,numba及其编译器importnumpyasnpiimportnumbafromnumbaimportjit第二步:传入numba装饰器jit并写入functions#传入jit,numba装饰器之一@jit(nopython=True)defgo_fast(a):#第一次调用时,函数被编译成机器码trace=0#假设输入变量是一个numpyarrayforiinrange(a.shape[0]):#Numba擅长处理循环trace+=np.tanh(a[i,i])#numba喜欢numpy函数returna+trace#numba喜欢numpybroadcastsnopython=True选项需要完整编译函数(以便完全删除Python解释器调用),否则会引发异常。这些异常通常表明函数中需要修改的地方才能获得比Python更好的性能。强烈建议您始终使用nopython=True。第三步:给函数传递实参#因为函数要求传入的参数是nunpy数组x=np.arange(100).reshape(10,10)#执行函数go_fast(x)第四步:加速bynumbaFunctionexecutiontime%timeitgo_fast(x)output:3.63μs±156nsperloop(mean±std.dev.of7runs,100000loopseach)第5步:没有numba加速的函数执行时间defgo_fast(a):#第一次调用时,函数被编译为机器码trace=0#假设输入变量是一个numpy数组foriinrange(a.shape[0]):#Numba擅长处理循环trace+=np.tanh(a[i,i])#numba喜欢numpy函数returna+trace#numba喜欢numpybroadcastx=np.arange(100).reshape(10,10)%timeitgo_fast(x)output:136μs每个循环±1.09μs(7次运行的平均值±标准偏差,每次10000次循环)结论:在numba加速下,代码执行时间为3.63微秒/循环。在没有numba加速的情况下,代码执行时间为136微秒/周期,比前者快40倍。numba让蟒蛇飞起来。我比较过使用numba之前和之后。python代码速度提升了40倍,但这还不是最快的。这次我们不用numpy数组,只用for循环,看看nunba有多爱for循环!#不使用numbadeft():x=0foriinnp.arange(5000):x+=ireturnx%timeit(t())output:408μs±9.73μsperloop(mean±std.dev.of7runs,1000loopseach)#Whenusingnumba@jit(nopython=True)deft():x=0foriinnp.arange(5000):x+=ireturnx%timeit(t())output:1.57μs±53.8nsperloop(mean±std.dev.of7runs,1000000loopseach)结论:使用numba前后分别是408微秒/循环和1.57微秒/循环,速度有已经大大提高了200多倍!结语numba大大提高了python代码的运行速度,对大数据时代的python数据分析能力有很大的提升。对于数据科学工作者来说,这真是一个幸运的工具!当然,numba对numpy和for循环以外的python代码帮助不大。不要指望numba可以帮助您加快从数据库中获取数据的速度。这真的不行。