一行代码让 Python 的运行速度提高100倍

python一直被病垢运行速度太慢,但是实际上python的执行效率并不慢,慢的是python用的解释器Cpython运行效率太差。

“一行代码让python的运行速度提高100倍”这绝不是哗众取宠的论调。

我们来看一下这个最简单的例子,从1一直累加到1亿。

最原始的代码:

结果:

我们来加一行代码,再看看结果:

结果:

是不是快了100多倍呢?

那么下面就分享一下“为啥numba库的jit模块那么牛掰?”

NumPy的创始人Travis Oliphant在离开Enthought之后,创建了CONTINUUM,致力于将Python大数据处理方面的应用。最近推出的Numba项目能够将处理NumPy数组的Python函数JIT编译为机器码执行,从而上百倍的提高程序的运算速度。

Numba项目的主页上有Linux下的详细安装步骤。编译LLVM需要花一些时间。
Windows用户可以从Unofficial Windows Binaries for Python Extension Packages下载安装LLVMPy、meta和numba等几个扩展库。

下面我们看一个例子:

numba中提供了一些修饰器,它们可以将其修饰的函数JIT编译成机器码函数,并返回一个可在Python中调用机器码的包装对象。为了能将Python函数编译成能高速执行的机器码,我们需要告诉JIT编译器函数的各个参数和返回值的类型。我们可以通过多种方式指定类型信息,在上面的例子中,类型信息由一个字符串’f8(f8[:])’指定。其中’f8’表示8个字节双精度浮点数,括号前面的’f8’表示返回值类型,括号里的表示参数类型,’[:]’表示一维数组。因此整个类型字符串表示sum1d()是一个参数为双精度浮点数的一维数组,返回值是一个双精度浮点数。
需要注意的是,JIT所产生的函数只能对指定的类型的参数进行运算:

如果希望JIT能针对所有类型的参数进行运算,可以使用autojit:

autoit虽然可以根据参数类型动态地产生机器码函数,但是由于它需要每次检查参数类型,因此计算速度也有所降低。numba的用法很简单,基本上就是用jit和autojit这两个修饰器,和一些类型对象。下面的程序列出numba所支持的所有类型:

工作原理
numba的通过meta模块解析Python函数的ast语法树,对各个变量添加相应的类型信息。然后调用llvmpy生成机器码,最后再生成机器码的Python调用接口。

meta模块
通过研究numba的工作原理,我们可以找到许多有用的工具。例如meta模块可在程序源码、ast语法树以及Python二进制码之间进行相互转换。下面看一个例子:

decompile_func能将函数的代码对象反编译成ast语法树,而str_ast能直观地显示ast语法树,使用这两个工具学习Python的ast语法树是很有帮助的。

而python_source可以将ast语法树转换为Python源代码:

decompile_pyc将上述二者结合起来,它能将Python编译之后的pyc或者pyo文件反编译成源代码。下面我们先写一个tmp.py文件,然后通过py_compile将其编译成tmp.pyc。

下面调用decompile_pyc将tmp.pyc显示为源代码:

llvmpy模块
LLVM是一个动态编译器,llvmpy则可以通过Python调用LLVM动态地创建机器码。直接通过llvmpy创建机器码是比较繁琐的,例如下面的程序创建一个计算两个整数之和的函数,并调用它计算结果。

f_add就是一个动态生成的机器码函数,我们可以把它想象成C语言编译之后的函数。在上面的程序中,我们通过ee.run_function调用此函数,而实际上我们还可以获得它的地址,然后通过Python的ctypes模块调用它。
首先通过ee.get_pointer_to_function获得f_add函数的地址:

然后通过ctypes.PYFUNCTYPE创建一个函数类型:

最后通过f_type将函数的地址转换为可调用的Python函数,并调用它:

numba所完成的工作就是:
解析Python函数的ast语法树并加以改造,添加类型信息;
将带类型信息的ast语法树通过llvmpy动态地转换为机器码函数,然后再通过和ctypes类似的技术为机器码函数创建包装函数供Python调用。

原文地址:http://blog.51cto.com/13870710/2296663

时间: 2024-08-05 23:49:56

一行代码让 Python 的运行速度提高100倍的相关文章

一行代码让你的python运行速度提高100倍

python一直被病垢运行速度太慢,但是实际上python的执行效率并不慢,慢的是python用的解释器Cpython运行效率太差. “一行代码让python的运行速度提高100倍”这绝不是哗众取宠的论调. 我们来看一下这个最简单的例子,从1一直累加到1亿. 最原始的代码: import timedef foo(x,y):        tt = time.time()        s = 0        for i in range(x,y):                s += i 

18小时内掌握Spark:把云计算大数据速度提高100倍以上

如何把云计算大数据处理速度提高100倍以上?Spark给出了答案. Spark是可以革命Hadoop的目前唯一替代者,能够做Hadoop做的一切事情,同时速度比Hadoop快了100倍以上,下图来自Spark的官方网站: Logistic regression in Hadoop and Spark 可以看出在Spark特别擅长的领域其速度比Hadoop快120倍以上! Spark是基于内存,是云计算领域的继Hadoop之后的下一代的最热门的通用的并行计算框架开源项目,尤其出色的支持Intera

只需一行代码!Python中9大时间序列预测模型

在时间序列问题上,机器学习被广泛应用于分类和预测问题.当有预测模型来预测未知变量时,在时间充当独立变量和目标因变量的情况下,时间序列预测就出现了. 预测值可以是潜在雇员的工资或银行账户持有人的信用评分.任何正式引入统计数据的数据科学都会遇到置信区间,这是某个模型确定性的衡量标准. 因此,预测一段时间内某些数据的价值需要特定的技术,并且需要多年的发展. 由于每种都有其特殊用途,必须注意为特定应用选择正确的技术.预测人员在技术选择中发挥作用,他们越了解预测可能性的范围,公司的预测工作就越有可能取得成

一行代码搭建 Python 静态服务器

如果电脑上安装有Python, 那么进入到目标文件夹,在终端中运行如下命令, 即可搭建映射当前目录的静态文件服务器: python -m SimpleHTTPServer 9000 默认端口号是8000,可以自定义端口号. 原文地址:https://www.cnblogs.com/wx1993/p/8297825.html

神奇的Python,一行代码能做哪些炫酷的事情?

可能大家在网上已经看过类似的python单行代码可以实现的功能,比如: 九九乘法表: print(' '.join([' '.join(['%s*%s=%-2s'%(y,x,x*y)for y in range(1,x+1)]) for x in range(1,10)])) 或者输出前100项斐波那契数列的值: print([x[0] for x in [ (a[i][0], a.append((a[i][1], a[i][0]+a[i][1]))) for a in ([[1,1]], )

【python】10分钟教你用python一行代码搞点大新闻

准备 相信各位对python的语言简洁已经深有领会了.那么,今天就带大家一探究竟.看看一行python代码究竟能干些什么大新闻.赶紧抄起手中的家伙,跟我来试试吧. 首先你得先在命令行进入python.像下面一样. 1> python2Python 3.6.0 (v3.6.0:41df79263a11, Dec 23 2016, 08:06:12) [MSC v.1900 64 bit (AMD64)] on win323Type "help", "copyright&q

用python一行代码实现1—100之和,你会吗

一行代码实现1—100之和 print(sum(range(1,101))) 程序运行结果: 5050 python2和python3的range(100)的区别 python2中的range返回的是一个列表 python3中的range返回的是一个迭代值 for i in range(1,10)在python2和python3中都可以使用,但是要生成1-10的列表,就需要用list(range(1,10)) python内建数据类型有哪些 整型--int   布尔型--bool   字符串--

Python一行代码

Python一行代码画出爱心 print'\n'.join([''.join([('SunShine-'[(x-y)%9]if((x*0.05)**2+(y*0.1)**2-1)**3-(x*0.05)**2*(y*0.1)**3<=0 else' ')for x in range(-30,30)])for y in range(15,-15,-1)])

Python人工智能之图片识别,Python3一行代码实现图片文字识别

1.Python人工智能之图片识别,Python3一行代码实现图片文字识别 2.tesseract-ocr安装包和中文语言包 注意: 原文地址:https://www.cnblogs.com/jycjy/p/8799295.html