首页>>后端>>Python->包含jit能使python快多少的词条

包含jit能使python快多少的词条

时间:2023-11-30 本站 点击:0

今天首席CTO笔记来给各位分享关于jit能使python快多少的相关内容,其中也会对进行详细介绍,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

本文目录一览:

1、如何让 Python 像 Julia 一样快地运行2、如何看待 python 的性能3、如何对python进行加速4、了解究竟哪个版本的Python是最快的5、各语言的性能比较,为什么python差那么多6、python的性能

如何让 Python 像 Julia 一样快地运行

Julia 与 Python

的比较

我是否应丢弃 Python 和其他语言,使用 Julia 执行技术计算?在看到 上的基准测试后,人们一定会这么想。Python

和其他高级语言在速度上远远有些落后。但是,我想到的第一个问题有所不同:Julia 团队能否以最适合 Python 的方式编写 Python 基准测试?

我对这种跨语言比较的观点是,应该根据要执行的任务来定义基准测试,然后由语言专家编写执行这些任务的最佳代码。如果代码全由一个语言团队编写,则存在其他语言未得到最佳使用的风险。

Julia 团队有一件事做得对,那就是他们将他们使用的代码发布到了 github 上。具体地讲,Python 代码可在此处找到。

第一眼看到该代码,就可以证实我所害怕的偏见。该代码是以 C 风格编写的,在数组和列表上大量使用了循环。这不是使用 Python 的最佳方式。

我不会责怪 Julia 团队,因为我很内疚自己也有同样的偏见。但我受到了残酷的教训:付出任何代价都要避免数组或列表上的循环,因为它们确实会拖慢 Python

中的速度,请参阅 Python 不是 C。

考虑到对 C 风格的这种偏见,一个有趣的问题(至少对我而言)是,我们能否改进这些基准测试,更好地使用 Python 及其工具?

在我给出答案之前,我想说我绝不会试图贬低 Julia。在进一步开发和改进后,Julia 无疑是一种值得关注的语言。我只是想分析 Python

方面的事情。实际上,我正在以此为借口来探索各种可用于让代码更快运行的 Python 工具。

在下面的内容中,我使用 Docker 镜像在 Jupyter Notebook 中使用 Python 3.4.3,其中已安装了所有的 Python 科学工具组合。我还会通过

Windows 机器上的 Python 2.7.10,使用 Anaconda 来运行代码。计时是对 Python 3.4.3 执行的。包含下面的所有基准测试的完整代码的 Notebook 可在此处找到。

鉴于各种社交媒体上的评论,我添加了这样一句话:我没有在这里使用 Python 的替代性实现。我没有编写任何 C

代码:如果您不信,可试试寻找分号。本文中使用的所有工具都是 Anaconda 或其他发行版中提供的标准的 Cython 实现。下面的所有代码都在单个 Notebook中运行。

我尝试过使用来自 github 的 Julia 微性能文件,但不能使用 Julia 0.4.2 原封不动地运行它。我必须编辑它并将 @timeit 替换为

@time,它才能运行。在对它们计时之前,我还必须添加对计时函数的调用,否则编译时间也将包含在内。我使用的文件位于此处。我在用于运行 Python 的同一个机器上使用 Julia 命令行接口运行它。

回页首

计时代码

Julia 团队使用的第一项基准测试是 Fibonacci 函数的一段简单编码。

def fib(n):

if n2:

return n

return fib(n-1)+fib(n-2)

此函数的值随 n 的增加而快速增加,例如:

fib(100) = 354224848179261915075

可以注意到,Python 任意精度 (arbitrary precision) 很方便。在 C 等语言中编写相同的函数需要花一些编码工作来避免整数溢出。在 Julia

中,需要使用 BigInt 类型。

所有 Julia 基准测试都与运行时间有关。这是 Julia 中使用和不使用 BigInt 的计时:

0.000080 seconds (149 allocations:10.167 KB)

0.012717 seconds (262.69 k allocations:4.342 MB)

在 Python Notebook 中获得运行时间的一种方式是使用神奇的 %timeit。例如,在一个新单元中键入:

%timeit fib(20)

执行它会获得输出:

100 loops, best of 3:3.33 ms per loop

这意味着计时器执行了以下操作:

运行 fib(20) 100 次,存储总运行时间

运行 fib(20) 100 次,存储总运行时间

运行 fib(20) 100 次,存储总运行时间

从 3 次运行中获取最小的运行时间,将它除以 100,然后输出结果,该结果就是 fib(20) 的最佳运行时间

这些循环的大小(100 次和 3 次)会由计时器自动调整。可能会根据被计时的代码的运行速度来更改循环大小。

Python 计时与使用了 BigInt 时的 Julia 计时相比出色得多:3 毫秒与 12 毫秒。在使用任意精度时,Python 的速度是 Julia 的 4

倍。

但是,Python 比 Julia 默认的 64 位整数要慢。我们看看如何在 Python 中强制使用 64 位整数。

回页首

使用 Cython 编译

一种编译方式是使用 Cython 编译器。这个编译器是使用 Python

编写的。它可以通过以下命令安装:

pip install Cython

如果使用 Anaconda,安装会有所不同。因为安装有点复杂,所以我编写了一篇相关的博客文章:将 Cython For Anaconda 安装在 Windows 上

安装后,我们使用神奇的 %load_ext 将 Cython 加载到 Notebook 中:

%load_ext Cython

然后就可以在我们的 Notebook 中编译代码。我们只需要将想要编译的代码放在一个单元中,包括所需的导入语句,使用神奇的 %%cython 启动该单元:

%%cython

def fib_cython(n):

if n2:

return n

return fib_cython(n-1)+fib_cython(n-2)

执行该单元会无缝地编译这段代码。我们为该函数使用一个稍微不同的名称,以反映出它是使用 Cython

编译的。当然,一般不需要这么做。我们可以将之前的函数替换为相同名称的已编译函数。

对它计时会得到:

1000 loops, best of 3:1.22 ms per loop

哇,几乎比最初的 Python 代码快 3 倍!我们现在比使用 BigInt 的 Julia 快 100 倍。

我们还可以尝试静态类型。使用关键字 cpdef 而不是 def 来声明该函数。它使我们能够使用相应的 C 类型来键入函数的参数。我们的代码变成了:

%%cython

cpdef long fib_cython_type(long n):

if n2:

return n

return fib_cython_type(n-1)+fib_cython_type(n-2)

执行该单元后,对它计时会得到:

10000 loops, best of 3:36 µs per loop

太棒了,我们现在只花费了 36 微秒,比最初的基准测试快约 100 倍!这与 Julia 所花的 80 毫秒相比更出色。

有人可能会说,静态类型违背了 Python

的用途。一般来讲,我比较同意这种说法,我们稍后将查看一种在不牺牲性能的情况下避免这种情形的方法。但我并不认为这是一个问题。Fibonacci

函数必须使用整数来调用。我们在静态类型中失去的是 Python 所提供的任意精度。对于 Fibonacci,使用 C 类型 long

会限制输入参数的大小,因为太大的参数会导致整数溢出。

请注意,Julia 计算也是使用 64 位整数执行的,因此将我们的静态类型版本与 Julia 的对比是公平的。

回页首

缓存计算

我们在保留 Python 任意精度的情况下能做得更好。fib 函数重复执行同一种计算许多次。例如,fib(20) 将调用 fib(19) 和

fib(18)。fib(19) 将调用 fib(18) 和 fib(17)。结果 fib(18) 被调用了两次。简单分析表明,fib(17) 将被调用 3

次,fib(16) 将被调用 5 次,等等。

在 Python 3 中,我们可以使用 functools 标准库来避免这些重复的计算。

from functools import lru_cache as cache

@cache(maxsize=None)

def fib_cache(n):

if n2:

return n

return fib_cache(n-1)+fib_cache(n-2)

对此函数计时会得到:

1000000 loops, best of 3:910 ns per loop

速度又增加了 40 倍,比最初的 Python 代码快约 3,600 倍!考虑到我们仅向递归函数添加了一条注释,此结果非常令人难忘。

Python 2.7 中没有提供这种自动缓存。我们需要显式地转换代码,才能避免这种情况下的重复计算。

def fib_seq(n):

if n 2:

return n

a,b = 1,0

for i in range(n-1):

a,b = a+b,a

return a

请注意,此代码使用了 Python 同时分配两个局部变量的能力。对它计时会得到:

1000000 loops, best of 3:1.77 µs per loop

我们又快了 20 倍!让我们在使用和不使用静态类型的情况下编译我们的函数。请注意,我们使用了 cdef 关键字来键入局部变量。

%%cython

def fib_seq_cython(n):

if n 2:

return n

a,b = 1,0

for i in range(n-1):

a,b = a+b,a

return a

cpdef long fib_seq_cython_type(long n):

if n 2:

return n

cdef long a,b

a,b = 1,0

for i in range(n-1):

a,b = a+b,b

return a

我们可在一个单元中对两个版本计时:

%timeit fib_seq_cython(20)

%timeit fib_seq_cython_type(20)

结果为:

1000000 loops, best of 3:953 ns per loop

10000000 loops, best of 3:51.9 ns per loop

静态类型代码现在花费的时间为 51.9 纳秒,比最初的基准测试快约 60,000(六万)倍。

如果我们想计算任意输入的 Fibonacci 数,我们应坚持使用无类型版本,该版本的运行速度快 3,500 倍。还不错,对吧?

回页首

使用 Numba 编译

让我们使用另一个名为 Numba 的工具。它是针对部分 Python 版本的一个即时

(jit) 编译器。它不是对所有 Python 版本都适用,但在适用的情况下,它会带来奇迹。

安装它可能很麻烦。推荐使用像 Anaconda 这样的 Python 发行版或一个已安装了 Numba 的 Docker 镜像。完成安装后,我们导入它的 jit 编译器:

from numba import jit

它的使用非常简单。我们仅需要向想要编译的函数添加一点修饰。我们的代码变成了:

@jit

def fib_seq_numba(n):

if n 2:

return n

(a,b) = (1,0)

for i in range(n-1):

(a,b) = (a+b,a)

return a

对它计时会得到:

1000000 loops, best of 3:225 ns per loop

比无类型的 Cython 代码更快,比最初的 Python 代码快约 16,000 倍!

回页首

使用 Numpy

我们现在来看看第二项基准测试。它是快速排序算法的实现。Julia 团队使用了以下 Python 代码:

def qsort_kernel(a, lo, hi):

i = lo

j = hi

while i hi:

pivot = a[(lo+hi) // 2]

while i = j:

while a[i] pivot:

i += 1

while a[j] pivot:

j -= 1

if i = j:

a[i], a[j] = a[j], a[i]

i += 1

j -= 1

if lo j:

qsort_kernel(a, lo, j)

lo = i

j = hi

return a

我将他们的基准测试代码包装在一个函数中:

import random

def benchmark_qsort():

lst = [ random.random() for i in range(1,5000) ]

qsort_kernel(lst, 0, len(lst)-1)

对它计时会得到:

100 loops, best of 3:18.3 ms per loop

上述代码与 C 代码非常相似。Cython 应该能很好地处理它。除了使用 Cython 和静态类型之外,让我们使用 Numpy

数组代替列表。在数组大小较大时,比如数千个或更多元素,Numpy 数组确实比

Python 列表更快。

安装 Numpy 可能会花一些时间,推荐使用 Anaconda 或一个已安装了 Python 科学工具组合的 Docker 镜像。

在使用 Cython 时,需要将 Numpy 导入到应用了 Cython 的单元中。在使用 C 类型时,还必须使用 cimport 将它作为 C 模块导入。Numpy

数组使用一种表示数组元素类型和数组维数(一维、二维等)的特殊语法来声明。

%%cython

import numpy as np

cimport numpy as np

cpdef np.ndarray[double, ndim=1] \

qsort_kernel_cython_numpy_type(np.ndarray[double, ndim=1] a, \

long lo, \

long hi):

cdef:

long i, j

double pivot

i = lo

j = hi

while i hi:

pivot = a[(lo+hi) // 2]

while i = j:

while a[i] pivot:

i += 1

while a[j] pivot:

j -= 1

if i = j:

a[i], a[j] = a[j], a[i]

i += 1

j -= 1

if lo j:

qsort_kernel_cython_numpy_type(a, lo, j)

lo = i

j = hi

return a

cpdef benchmark_qsort_numpy_cython():

lst = np.random.rand(5000)

qsort_kernel_cython_numpy_type(lst, 0, len(lst)-1)

对 benchmark_qsort_numpy_cython() 函数计时会得到:

1000 loops, best of 3:1.32 ms per loop

我们比最初的基准测试快了约 15 倍,但这仍然不是使用 Python 的最佳方法。最佳方法是使用 Numpy 内置的 sort()

函数。它的默认行为是使用快速排序算法。对此代码计时:

def benchmark_sort_numpy():

lst = np.random.rand(5000)

np.sort(lst)

会得到:

1000 loops, best of 3:350 µs per loop

我们现在比最初的基准测试快 52 倍!Julia 在该基准测试上花费了 419 微秒,因此编译的 Python 快 20%。

我知道,一些读者会说我不会进行同类比较。我不同意。请记住,我们现在的任务是使用主机语言以最佳的方式排序输入数组。在这种情况下,最佳方法是使用一个内置的函数。

如何看待 python 的性能

python的性能要从几个方面看,如果只看标准版的语言实现本身,性能可以说是很差的,因为动态语言本身就决定了很多东西要运行时检查,并且标准版没有对字节码做jit等优化,等于是直接解释

不过,由于python很多基础库是用C实现,如果库执行比例较大,速度还是可以接受,典型例子是python的高精度计算,long类型是C语言实现,而jre中java的BigInteger是用java自己实现,因此高密度的高精度计算python还要快些,因此很多系统采用核心用C改写的方式,和python结合使用,根据二八定律,只需改写较少的模块就能较大提高效率

当然,也可以直接用pypy等jit解释器,效率也能提高不少,虽然和静态类型语言还是有差距

最后说明一点的是,效率问题在计算比较密集的时候才体现性能瓶颈,有些网站虽然看上去业务很大,但业务本身可能不是很复杂,访问量也并不是特别高,这个也可以估算一下

如何对python进行加速

对python进行加速的方法:

1、使用哈希表的数据结构

如果在程序中遇到大量搜索操作时,并且数据中没有重复项,则可以使用查找而不是循环。

2、矢量化取代循环

尽量使用基于C构建的Python库,例如Numpy,Scipy和Pandas,并且利用矢量化同时处理来取代程序中编写多次处理数组单个元素的循环,循环可能是程序优化最容易被拿来开刀的地方了。

3、精简代码行数

在编程时,尽量使用一些python的内置函数来精简代码行数,是代码显得简洁凝练,大大提高代码运行效率。

4、使用多进程

一般计算机都是多进程的,那么在执行操作时可以使用Python中的multiproccessing。多进程可在代码中实现并行化。 当您要实例化新进程,访问共享内存时,多进程成本很高,因此如果有大量数据处理时可以考虑使用多进程。

5、使用Cpython

Cython是一个静态编译器,可以为您优化代码。加载cypthonmagic扩展并使用cython标记使用cython编译代码。

6、尽量使用csv替代xlsx

在进行数据处理时, 我需要更长的时间才能将数据加载到excel文件或从excel文件保存数据。 相反,我选择了创建多个csv文件的路径,并创建了一个文件夹来对文件进行分组。

7、使用Numba

它是一个JIT(即时)编译器。 通过装饰器,Numba将带注释的Python和NumPy代码编译为LLVM 。将您的功能分为两部分:

执行计算的函数 - 使用@autojit进行装饰

执行IO的功能

更多Python知识请关注Python视频教程栏目。

了解究竟哪个版本的Python是最快的

哪个版本的 Python 是最快的?当然,“这取决于”多种因素,需要根据不同的条件情况来进行测试。Python 3.7 是速度最快的“官方”Python 版本,但PyPy 则是最快的。

虽然PyPy 是最快的,但它并不能广泛的应用。

PyPy 拥有即时(JIT)编译器,因此它比 CPython 快。JIT

编译器具有很大的好处,因为它们在执行可预测的重复性任务时非常高效。Python

性能测试的其中一个特点是,你需要多次运行同一段代码以使其准确无误,从而减少应用程序的错误边界。因此,PyPy 面对这样的测试性能更优。

JIT 编译器,尤其是 PyPy 的 JIT 编译器最显著的缺点是启动成本高。另一个缺点是许多 C

语言扩展程序缺乏兼容性。因为“Python”(CPython,官方的 PSF Python)是用 C 语言编写的,PyPi

上的许多第三方扩展利用了这一点。Numpy 就是一个很好的例子,Numpy 的大部分代码都是用优化的 C 代码编写的。当你执行 pip install

numpy 命令时,它会使用本地 C 编译器为你的 Python 运行时建立一个二进制库,供 Python 程序使用。

由于 PyPy 是用 Python 编写的,很多模块根本无法在 PyPy 中工作,所以你需要经常进行检查

各语言的性能比较,为什么python差那么多

Java的JIT优化了那么多年,比Go生成的本地程序还要快可以理解。进行的对10个升序的数进行1亿次冒泡降序排序,Java耗时接近GCC -O优化的本地程序,虽然内存占用更大。

Node.JS有V8这种高效成熟的JIT编辑器,虽然比不上Java HotSpot JIT,但轻松就能秒其他没有JIT脚本几条街。

不过Python的性能真的不怎么样,1亿次累加求和,PHP7耗时1.855秒,PHP5耗时3.855秒,而Python2.7则耗时9.460秒,是PHP7耗时的5倍。

python的性能

我用python执行时间23秒,用pypy执行时间1.54秒,用numba加速为1.5秒,c语言在本机macos上执行时间1.3秒,java运行速度1.45秒(jre8),详细见图片,可见引入jit编译后,性能直逼c语言,而写python比写c容易太多,比java简洁,写代码速度也是非常非常重要。由于历史原因,很多python库用的c语言库,如pandas(pandas的矩阵计算用numpy优化过非常快,可能比手写c语言循环还要快),可以通过设计来分离c语言加速后的python代码和pure python,分别用不同的加速方法,如numba可以单独加速一个函数,把需要大量计算的放在一个函数用numba加速(numbapro支持显卡加速但是商业版的)。

所以只适当设计一下,python在一般计算问题下有这些解决方案下性能不是问题,实在不行,你还可以用boost::python来写个c/c++调用库来解决性能问题。

下面的测试说明,对于性能,原生python比较慢,在windows下python比linux,macos要快,用pypy后相当于java,c#速度,pypy,c#在windows下受益msvc表现较快,,go语言速度表现比较稳定,c语言理论上是最快,但受环境和编译器影响较大。对c#,java可能在GC垃圾回收时会表现不稳定,因为在oop中有大量计算后可能要回收垃圾内存对象,这个没有用到oop,只是纯计算,理论上还是c/c++语言最快。

python和java比,运行速度比java慢,java强大于改进n次的强大jre,但python在很多领域能调用很多现成的开源库,在数据分析中有优势,pyhton的代码比java要简洁,容易入门和使用。在优化的计算库帮助下,如numpy numba,pandas,scikit-learn,python的实际问题运算性能并不低于java。java主要是框架太多,相对复杂,java主要用于业务程序开发,符合软件工程理论,可伸缩性强,强类型有利于对程序的静态检查分析。java随着安卓,hadoop,spark的兴起,加入java语言的公司很多,性能也可以通过优化解决很多问题。很多服务器如ubuntu server,centos都默认支持python,而java虚拟机需要安装配置,python的安装使用也相对简单。python的库有开箱即用感,很多业务领域,你可能还在用oop写代码,考虑设计模式,用锄头挖沟时,而python调用挖掘机api已经炒菜完工开饭了,缺点是油耗比较大。

结语:以上就是首席CTO笔记为大家整理的关于jit能使python快多少的全部内容了,感谢您花时间阅读本站内容,希望对您有所帮助,更多关于、jit能使python快多少的相关内容别忘了在本站进行查找喔。


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