作者:perrygeo
译者:赖勇浩(http://laiyonghao.com)
我最喜欢的是Python,它的代码优雅而实用,可惜纯粹从速度上来看它比大多数语言都要慢。大多数人也认为的速度和易于使用是两极对立的——编写C代码的确非常痛苦。而 Cython 试图消除这种两重性,并让你同时拥有 Python 的语法和 C 数据类型和函数——它们两个都是世界上最好的。请记住,我绝不是我在这方面的专家,这是我的第一次Cython真实体验的笔记:
编辑:根据一些我收到的反馈,大家似乎有点混淆——Cython是用来生成 C 扩展到而不是独立的程序的。所有的加速都是针对一个已经存在的 Python 应用的一个函数进行的。没有使用C 或 Lisp 重写整个应用程序,也没有手写C扩展。只是用一个简单的方法来整合C的速度和C数据类型到 Python 函数中去。
现在可以说,我们能使下文的great_circle 函数更快。所谓great_circle 是计算沿地球表面两点之间的距离的问题:
让我们调用它 50 万次并测定它的时间 :
约2.2秒。它太慢了!
让我们试着快速地用Cython改写它,然后看看是否有差别:
请注意,我们仍然importmath——cython让您在一定程度上混搭Python和C数据类型在。转换是自动的,但并非没有代价。在这个例子中我们所做的就是定义一个Python函数,声明它的输入参数是浮点数类型,并为所有变量声明类型为C浮点数据类型。计算部分它仍然使用了Python的 math 模块。
现在我们需要将其转换为C代码再编译为Python扩展。完成这一部的最好的办法是编写一个名为setup.py发布脚本。但是,现在我们用手工方式,以了解其中的巫术:
现在你应该有一个c1.so(或.dll)文件,它可以被Python import。现在运行一下:
约1.8秒。并没有我们一开始期望的那种大大的性能提升。使用 python 的 math 模块应该是瓶颈。现在让我们使用C标准库替代之:
与 import math 相应,我们使用cdef extern的方式使用从指定头文件声明函数(在此就是使用C标准库的math.h)。我们替代了代价高昂的的Python函数,然后建立新的共享库,并重新测试:
现在有点喜欢它了吧?0.4秒-比纯Python函数有5倍的速度增长。我们还有什么方法可以再提高速度?c2.great_circle()仍是一个Python函数调用,这意味着它产生Python的API的开销(构建参数元组等),如果我们可以写一个纯粹的C函数的话,我们也许能够加快速度。
请注意,我们仍然有一个Python函数(def),它接受一个额外的参数 num。这个函数里的循环使用for i from 0 < = i< num:,而不是更Pythonic,但慢得多的for i in range(num):。真正的计算工作是在C函数(cdef)中进行的,它返回float类型。这个版本只要0.2秒——比原先的Python函数速度提高10倍。
为了证明我们所做的已经足够优化,可以用纯C写一个小应用,然后测定时间:
用gcc -lm -octest ctest.c编译它,测试用time./ctest...大约0.2秒。这使我有信心,我Cython扩展相对于我的C代码也极有效率(这并不是说我的C编程能力很弱)。
能够用 cython 优化多少性能通常取决于有多少循环,数字运算和Python函数调用,这些都会让程序变慢。已经有一些人报告说在某些案例上 100 至 1000 倍的速度提升。至于其他的任务,可能不会那么有用。在疯狂地用 Cython重写 Python 代码之前,记住这一点:
"我们应该忘记小的效率,过早的优化是一切罪恶的根源,有 97% 的案例如此。"——DonaldKnuth
换句话说,先用 Python 编写程序,然后看它是否能够满足需要。大多数情况下,它的性能已经足够好了……但有时候真的觉得慢了,那就使用分析器找到瓶颈函数,然后用cython重写,很快就能够得到更高的性能。
外部链接
WorldMill(http://trac.gispython.org/projects/PCL/wiki/WorldMill)——由Sean Gillies 用 Cython 编写的一个快速的,提供简洁的 python 接口的模块,封装了用以处理矢量地理空间数据的 libgdal 库。
编写更快的 Pyrex 代码(http://www.sagemath.org:9001/WritingFastPyrexCode)——Pyrex,是 Cython 的前身,它们有类似的目标和语法。
分享到:
相关推荐
请记住,我绝不是我在这方面的专家,这是我的第一次Cython真实体验的笔记:编辑:根据一些我收到的反馈,大家似乎有点混淆——Cython是用来生成 C 扩展到而
而 Cython 试图消除这种两重性,并让你同时拥有 Python 的语法和 C 数据类型和函数——它们两个都是世界上最好的。请记住,我绝不是我在这方面的专家,这是我的第一次Cython真实体验的笔记: 编辑:根据一些我收到的...
《Cython入门》 示例 http://blog.csdn.net/i2cbus/article/details/18181637
[Packt Publishing] Cython 编程学习教程 (英文版) [Packt Publishing] Learning Cython Programming (E-Book) ☆ 图书概要:☆ Expand your existing legacy applications in C using Python Overview Extend ...
参考Cython官方文档编写而来的一个Cython封装C++的示例demo,可入门学习。
cython入门学习手册,用来指导蒋c语言写的程序扩展成python的模块
It’s possible with Cython, the compiler and hybrid programming language used by foundational packages such as NumPy, and prominent in projects including Pandas, h5py, and scikits-learn. In this ...
Cython封装Callback函数文章 示例 http://blog.csdn.net/i2cbus/article/details/18415333
Cython: A Guide for Python Programmers covers all you need to know about the eponymous creole programming language and Python-to-C compiler. If you have heard of Cython and want to find out more, or ...
此为适用于linux系统python3.6的cython安装包,版本为0.29
cython_bbox-0.1.3 未修改pip源码
Learning Cython Programming
python库。 资源全名:Cython-0.29.3.tar.gz
Python第三方包 Cython
引言 通常,在 Python 中写循环(特别是多重循环)非常的慢,在文章 //www.jb51.net/article/133807.htm中,我们的...cimport cython DTYPE = np.float ctypedef np.float_t DTYPE_t def update_state(np.ndarray[DTYP
Cython-0.29.30-py3-none-any.whl
OrderedDict的Cython实现
详细介绍了Cython文件在window与linux下的编译,以实际例子说明。
Cython是一个编程语言,它通过类似Python的语法来编写C扩展并可以被Python调用.既具备了Python快速开发的特点,又可以让代码运行起来像C一样快,同时还可以方便地调用C library。译出最终的Python可调用的模块。