简单 Python C 扩展的编写及其对 Python 递归性能的提高

前些天在 V2EX 闲逛的时候看到了一个很有意思的帖子:

http://www.v2ex.com/t/48917

这个帖子基本的含义就是使用递归方法计算斐波那契数列第N项的值,对应的 Python 代码如下(代码来自《fibonacci(40) benchmark》一文):

另外插一句:这里用的递归实际上是一种十分低效的计算斐波那契数列的方法,如果改成循环性能将会大大提升,不过我们是在 “benchmark” ,大量递归产生的大量函数调用正是这个测试的测试点。

def fibonacci(n):    if n < 2:        return n    return fibonacci(n - 2) + fibonacci(n - 1)print fibonacci(40)

用服务器(Intel(R) Xeon(R) CPU E5640 ?@ 2.67GHz + Linux 64 bit + Python 2.7.3)运行了一下,Python 计算 fibonacci(40) 耗时 54.6027610302 秒,简直慢的让人发指。

当然实际上这个测试对 Python 不是特别公平,因为 Python 最忌讳深度递归,参考《Python recursion performance test》一文,作者最后总结:the bottomline is that you shouldn’t use recursion in python.

如果我们给 Python 写一个 C Extension ,来计算 fibonacci ,会不会快一点呢?

这是我写的 fib.c

代码有详细注释,应该很好理解。

然后创建一个简单的 setup.py 用来编译:

from distutils.core import setup, Extensionsetup(    ext_modules=[Extension("fib", ["fib.c"])])

然后执行:

pyrite-n1:~/dndx> python setup.py build_ext -irunning build_extbuilding 'fib' extensiongcc -pthread -fno-strict-aliasing -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -D_GNU_SOURCE -fPIC -fwrapv -DNDEBUG -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -D_GNU_SOURCE -fPIC -fwrapv -fPIC -I/usr/include/python2.7 -c fib.c -o build/temp.linux-x86_64-2.7/fib.ogcc -pthread -shared -Wl,-z,relro build/temp.linux-x86_64-2.7/fib.o -L. -lpython2.7 -o /home/ugrad1/datong/dndx/fib.so

这样你就在 fib.c 的同目录下生成了 fib.so ,来编写一个简单的脚本比较两者性能差距:

import fibimport timeimport sysstart = time.time()print(fib.fib(40))print(time.time() - start)sys.stdout.flush()def fibonacci(n):    if n < 2:        return n    return fibonacci(n - 2) + fibonacci(n - 1)start = time.time()print(fibonacci(40))print(time.time() - start)sys.stdout.flush()

给它起一个名字放在 fib.so 的同目录下,运行(//后为我对结果的注释):

pyrite-n1:~/dndx> python test.py 102334155 //Result of C version0.640976905823 //Time of C version102334155 //Result of pure Python version54.8752160072 //Time of pure Python version

结果相当让人震惊,在我的机器上,性能提升了 8561% 。

简单 Python C 扩展的编写及其对 Python 递归性能的提高

相关文章:

你感兴趣的文章:

标签云: