专栏名称: Python开发者
人生苦短,我用 Python。伯乐在线旗下账号「Python开发者」分享 Python 相关的技术文章、工具资源、精选课程、热点资讯等。
目录
相关文章推荐
Python爱好者社区  ·  很严重了,大家别轻易离职 ·  昨天  
Python爱好者社区  ·  月薪3万35岁脑干出血程序员:ICU躺了28 ... ·  3 天前  
Python爱好者社区  ·  务必立即拿下软考证(政策红利) ·  4 天前  
Python爱好者社区  ·  Science披露:近3年,垃圾论文激增,9 ... ·  4 天前  
51好读  ›  专栏  ›  Python开发者

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

Python开发者  · 公众号  · Python  · 2017-05-19 16:48

正文

请到「今天看啥」查看全文


, 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







请到「今天看啥」查看全文