摘要:最近coding时用到了Python装饰器,它的作用太强大了,而且使用也简单,解决了我代码中大量重复计算的瓶颈,下面以计算Fibonacci数列为例来说明问题: C语言版:

编译:gcc -O3 -o fib fib.c 运行:

3f562cff3add213bb51913f769bf144c18 

用时3.28s。 来看下纯Python版的:

运行:

70505bda3a44ca5f271f9fac06dd3ada 

用时40.19s,本来是想算45的,无奈迟迟不出结果。 和上面的C版用时相差几百倍多,因为此处计算的是40,当数据越大,则fib的调用呈指数级上升,所以此处预估为几百倍不算夸张,下面会分析此处fib重复调用次数。从这里可以看出Python的确不适合做这种大量重复计算,所以我们就想到了用C/C++来扩展Python,提高计算速度,用Python使用bitey调用C模块中的方法来重写。 Python+ctypes版的:

运行:

555e2cfa4f5c65888582cf29c37064a0 

用时9.88s,明显比纯Python版快,但还是和纯C版的相差三倍左右。 再来看下Python+bitey版的:

运行:

5f39ca556a142e8cef1f083d9d0ae703

用时6.58s,可以看出比ctypes版的要好点,但比纯C版还是要差些,不过已经很不错了,应该是clang+llvm的功劳。 现在回过头来分析下纯Python版的为什么会这么慢,运行: 8c3474d840ec9a9d81db0365421c98661

发现对fib调用了331160281次,不慢都不正常了,基于Fibonacci数列的特点,我们可以想办法记录上一次计算后的结果,比如计算f(10),可以把计算过的f(9)和f(8)的结果直接返回,而不用递归下去。刚好Python装饰器可以用来记录上次计算的结果,关于Python装饰器的使用请看Python装饰器与面向切面编程。 Python装饰器版:

运行 :

1b43f01bfd30dacae5809d361e492f3a

用时0.02s,比纯C版的都快150多倍!这就是经过装饰器处理后的效果,其实C也能做到缓存结果,但比起Python这种简单明了的方式来说它太复杂了。 总结:在提升python的处理速度时,我们可以通过boost/ctypes/bitey调用c/c++写的模块,也可以用cython来编译,但最终利用语言自身的特性来优化算法才是王道。 转载:http://blog.csdn.net/hechaoyuyu/article/details/8240441