如何使用C语言优化Python代码
如何使用C语言优化Python代码
Cython是Python编程语言的编译器,旨在优化性能并形成扩展的Cython编程语言。作为Python的扩展,Cython也是Python语言的超集,它支持调用C函数,并在变量和类属性上声明C类型。这使得包装外部C库、将C嵌入现有应用程序或以Python的语法编写C扩展变得像Python本身一样简单。
Cython通常用于创建加速Python代码执行的C模块。在解释语言效率不高的复杂应用程序中,这一点很重要。
![](https://filescdn.proginn.com/ddca3268cad527127045f11878cc6729/9745bd6cc09c3f2549f5a25f503c501d.webp)
![](https://filescdn.proginn.com/096dee496d918776149332b532f76d25/8f0f35deedef718d597fad082801b73a.webp)
可以使用Python在Linux、BSD、Windows或macOS上安装Cython:
![](https://filescdn.proginn.com/e881f62f82cda94ca5a50fa2fccf4dac/90ea6dfc89777bd235407c5bf26d3f78.webp)
![](https://filescdn.proginn.com/3f532e66f4e9ed38a1043f8015a3f842/ea22c8d82c693c532d1e96ff9f55e9f7.webp)
![](https://filescdn.proginn.com/096dee496d918776149332b532f76d25/8f0f35deedef718d597fad082801b73a.webp)
从Cython开始的一个好方法是使用一个简单的“Hello World ”应用程序。这不是优势的最好证明,但它显示了你使用时会发生什么。
首先,在一个名为hello.pyx的文件中创建这个简单的Python脚本(.pyx扩展名并不神奇,从技术上讲,它可以是任何东西,但它是Cython的默认扩展名):
![](https://filescdn.proginn.com/9241f8c2ebfda2fa3a99160a98b58e29/d82895d27844dbe6c248213fd9e2ba82.webp)
接下来,创建一个Python安装脚本。setup.py文件类似于Makefile的Python版本,Cython可以使用它来处理Python代码:
![](https://filescdn.proginn.com/f4ec48c500eb42f56aff64747ef6ff30/1800c5065594262cb51c4eb65ab88270.webp)
最后,使用Cython将Python脚本转换为C代码:
![](https://filescdn.proginn.com/e9dc6d2970a631972636005856522477/c4f342da5d0a53b8f224fe5c3b19412c.webp)
要使用Python“Hello World”脚本的C代码版本,请打开Python提示并导入创建的新模块:
![](https://filescdn.proginn.com/c69a3a0197b154eae80b44baf96c4503/fd51a16a7dd2d8658170fb231629c406.webp)
将C代码集成到Python中
计算能力的一个很好的通用测试是计算素数。素数是大于1的正数,只有在除以1或本身时才产生正整数。理论上很简单,但随着数字变大,计算要求也增加了。在纯Python中,它可以在10行代码下完成:
![](https://filescdn.proginn.com/b9b1ca6f86654f9fb8671854afbfcd29/eb46088fcb1fd6d3f4f0584c56ae3195.webp)
此脚本在成功后将保持不变,如果数字不是素数,则返回一条消息:
$ ./prime.py 3
$ ./prime.py 4
Not prime.
将其转换为Cython需要进行一些工作,一方面使代码适合用作库,另一方面使性能提高。
![](https://filescdn.proginn.com/096dee496d918776149332b532f76d25/8f0f35deedef718d597fad082801b73a.webp)
许多用户将Python作为一种脚本语言进行学习:把将要执行的步骤告诉Python,然后它就可以完成工作。当了解更多有关Python(以及一般来说是开放源代码编程)的知识时,会发现许多最强大的代码包含在其他应用程序可以利用的库中。代码越不具体,程序员将其重新用于其他应用程序的可能性就越大。
对于这个简单的质数计算器,将其转换为Cython的过程是通过设置脚本开始的:
![](https://filescdn.proginn.com/a97b4e8dfdd894fa915828e4ad6a4da1/8ea16471c204124f52bbff4b5cd15208.webp)
![](https://filescdn.proginn.com/096dee496d918776149332b532f76d25/8f0f35deedef718d597fad082801b73a.webp)
$ python setup.py build_ext --inplace
到目前为止,一切似乎都运行良好,但是当尝试导入和使用新模块时,会出现错误:
![](https://filescdn.proginn.com/f8580e6c3893ffaa90328d191bb75056/01d9df9bca9c367df3fd9ffe7599a4a6.webp)
问题在于,Python脚本希望从终端运行,在终端上,参数(在这种情况下,是要测试为质数的整数)很常见。需要修改脚本,以便可以将其用作库。
![](https://filescdn.proginn.com/096dee496d918776149332b532f76d25/8f0f35deedef718d597fad082801b73a.webp)
库不使用系统参数,而是接受其他代码的参数。不用使用sys.argv来引入用户输入,而是使代码成为一个接受称为number(或num或喜欢的任何变量名)的参数的函数:
![](https://filescdn.proginn.com/3a4b3255f446cbaf6bf6bc3261b47ef4/a3459b64ac67a7ea0e5446d9cc22138b.webp)
这使脚本难以测试,因为当在Python中运行代码时,永远不会执行calculate函数。但是,Python程序员针对此问题设计了一种通用的解决方法,即使不是直观的方法。当Python解释器执行Python脚本时,有一个名为__name__的特殊变量被设置为__main__,但是当它作为模块导入时,__name__被设置为模块的名称。通过利用这一点,您可以编写一个既是Python模块又是有效的Python脚本的库:
![](https://filescdn.proginn.com/e374d444c82f16dacc0de333ee59e629/d46a460fa87b7d6c437af10d0bf75ad6.webp)
现在,可以将代码作为命令运行:
$ python ./prime.py 4
Not a prime
可以将其转换为Cython以用作模块:
![](https://filescdn.proginn.com/615e0295b1151421ab75e2d43a7a164c/02c22bbfc26424140f785afadb5d5f1a.webp)
![](https://filescdn.proginn.com/096dee496d918776149332b532f76d25/8f0f35deedef718d597fad082801b73a.webp)
使用Cython将代码从纯Python转换为C可能会很有用。但是还有Cython功能可帮助用户在转换前优化代码,还可以选择分析代码以查找Cython与C交互的时间,等等。如果使用的是Python,希望通过C代码增强代码,或者进一步了解库如何提供比脚本更好的可扩展性,或者只是对Python和C如何协同工作感到好奇,那么请开始使用Cython。
![](https://filescdn.proginn.com/425452746fe5e88a00b46b0a896396d9/47a9f49a9d2514ebc248d338868346e7.webp)
![](https://filescdn.proginn.com/9692c3a6a6c9ced0ddae0c0692070693/fc00518b9dcc9a2daad5627715f78fd9.webp)