龙空技术网

使用Cython为Python编写更快的C扩展

少儿编程Prog61 73

前言:

此时大家对“c给python写扩展”大体比较看重,大家都想要了解一些“c给python写扩展”的相关文章。那么小编同时在网上搜集了一些有关“c给python写扩展””的相关内容,希望大家能喜欢,姐妹们一起来了解一下吧!

Python是目前使用的最流行的编程语言之一,而且有充分的理由:它是开放源码的,有广泛的用途(如web编程、商业应用程序、游戏、科学编程等等),并且有一个活跃的、专门的社区支持它。这个社区是我们在Python包索引(PyPI)中拥有如此大的、各种各样的软件包的原因,这些软件包可以扩展和改进Python,并解决不可避免的小故障。

Cython

使用Python很有趣,但有时用它编写的程序可能很慢。所有的运行时动态调度都要付出高昂的代价:有时它比用C或Rust这样的系统语言编写的等价代码慢10倍。

将一段代码迁移到一种全新的语言中,在工作效率和可靠性方面都要付出很大的代价:所有的手工重写工作都不可避免地会引入bug。我们可以鱼与熊掌兼得吗?

为了优化这个练习,我们需要一些慢的东西。还有什么比偶然实现的斐波那契数列的指数级实现更慢的呢?

def fib(n):    if n < 2:        return 1    return fib(n-1) + fib(n-2)

由于对fib的调用会导致两个调用,所以这个效率低下的算法需要很长时间才能执行。例如,在我的新笔记本电脑上,fib(36)大约需要4.5秒。当我们探索Python的Cython扩展如何提供帮助时,这4.5秒将是我们的基线。

使用Cython的正确方法是将其集成到setup.py中。但是,快速简便的方法是使用pyximport。让我们将上面的fib代码放在fib.pyx中,然后使用Cython运行它。

>>> import pyximport; pyximport.install()>>> import fib>>> fib.fib(36)

只需使用Cython而不需要修改代码,就可以将算法在我笔记本电脑上花费的时间减少到2.5秒左右。几乎不费吹灰之力,运行时间就减少了50%!

付出更多的努力,我们可以使它变得更快。

cpdef int fib(int n):    if n < 2:        return 1    return fib(n - 1) + fib(n - 2)

我们将fib中的代码移到用cpdef定义的函数中,并添加了两个类型注释:它接受一个整数并返回一个整数。

这样可以更快,大约0.05秒。太快了!

因此,下一次您的Python代码在CPU上花费太长时间时,可以看看Cython是否可以修复这些问题。

标签: #c给python写扩展