什么是赛顿? Python以C的速度
Python以其成为最方便,功能最丰富,最实用的编程语言之一而闻名。 执行速度? 没那么多。
输入Cython。 Cython语言是Python的超集,可编译为C,根据手头的任务,其性能提升范围可从几个百分点到几个数量级。 对于受Python本机对象类型限制的工作,提速不会很大。 但是对于数值运算或任何不涉及Python自身内部的运算,其收益可能是巨大的。
[ 同样在InfoWorld上:如何在Python中使用asyncio ]
使用Cython,您可以绕过Python的许多本机限制或完全超越它们,而不必放弃Python的便捷性。 在本文中,我们将介绍Cython背后的基本概念,并创建一个使用Cython加速其功能之一的简单Python应用程序。
相关视频:使用Cython加速Python
将Python编译为C
Python代码可以直接调用C模块。 这些C模块可以是通用C库,也可以是专门为与Python合作而构建的库。 Cython生成第二种模块:与Python内部通信的C库,可以与现有的Python代码捆绑在一起。
根据设计,Cython代码看起来很像Python代码。 如果您向Cython编译器提供Python程序(都支持Python 2.x和Python 3.x),则Cython将按原样接受它,但是Cython的本机加速将不起作用。 但是,如果您使用Cython的特殊语法中的类型注释修饰Python代码,则Cython将能够用快速的C等效项替换缓慢的Python对象。
请注意,Cython的方法是增量式的 。 这意味着开发人员可以从现有的 Python应用程序开始,并通过对代码进行局部更改来加快它的速度,而不是从头开始重写整个应用程序。
这种方法与软件性能问题的本质相吻合。 在大多数程序中,绝大多数CPU密集型代码都集中在几个热点上,这是Pareto原理的一种版本,也称为“ 80/20”规则。 因此,Python应用程序中的大多数代码不需要进行性能优化,仅需几个关键部分。 您可以将这些热点逐步转换为Cython,从而在最重要的地方获得所需的性能提升。 程序的其余部分可以保留在Python中,以方便开发人员。
如何使用Cython
请考虑以下来自Cython文档的代码:
def f(x): return x**2-x
def integrate_f(a, b, N): s = 0 dx = (b-a)/N for i in range(N): s += f(a+i*dx) return s * dx
这是一个玩具示例,它不是积分函数的非常高效的实现。 作为纯Python代码,它很慢,因为Python必须在机器本地数字类型与其自身的内部对象类型之间来回转换。
现在考虑相同代码的Cython版本,并强调Cython的附加功能:
cdef double f( double x): return x**2-x
def integrate_f( double a, double b, int N): cdef int i cdef double s, x, dx s = 0 dx = (b-a)/N for i in range(N): s += f(a+i*dx) return s * dx
如果我们为函数参数和函数主体中使用的变量( double
, int
等) 明确声明变量类型 ,Cython会将所有这些变量转换为C。我们还可以使用cdef
关键字定义主要在C语言中实现的函数可提高速度,尽管这些函数只能由其他Cython函数调用,而不能由Python脚本调用。 (在上面的示例中,只能由另一个Python脚本调用integrate_f
。)
请注意,我们的实际代码更改了多少。 我们要做的就是在现有代码中添加类型声明,以显着提高性能。
Cython的优势
除了能够加快您已经编写的代码的速度之外,Cython还具有其他一些优点:
使用外部C库可以更快
NumPy之类的Python包将C库包装在Python接口中,以使其易于使用。 但是,通过这些包装在Python和C之间来回移动会减慢速度。 Cython允许您直接与基础库进行对话,而无需使用Python。 (也支持C ++库。)
您可以同时使用C和Python内存管理
如果您使用Python对象,则它们与常规Python一样由内存管理和垃圾回收。 但是,如果您要创建和管理自己的C级结构,并使用malloc
/ free
与它们一起工作,则可以这样做。 只要记得自己清理一下即可。
您可以根据需要选择安全性或速度
Cython通过装饰器和编译器指令(例如@boundscheck(False)
)自动执行C语言中常见问题的运行时检查,例如对数组的越界访问。 因此,尽管可能以原始性能为代价,但Cython生成的C代码默认情况下比手动滚动的C代码安全得多。
如果您确信不需要在运行时进行这些检查,则可以在整个模块上或仅在某些选择的功能上禁用它们以提高速度。
Cython还允许您本地访问使用缓冲区协议直接访问存储在内存中的数据的Python结构(无需中间复制)。 Cython的内存视图使您可以高速处理这些结构,并以适合任务的安全级别进行工作。 例如,可以以这种方式(快速)读取Python字符串基础的原始数据,而不必经过Python运行时(缓慢)。
Cython C代码可以受益于发布GIL
Python的全局解释器锁(GIL)在解释器中同步线程,从而保护对Python对象的访问并管理资源争用。 但是GIL被广泛批评为性能更好的Python的绊脚石,尤其是在多核系统上。
如果您有一段代码没有引用Python对象并执行了长时间运行的操作,则可以with nogil:
指令对其进行标记,以使其在没有GIL的情况下运行。 这使Python解释器可以腾出时间做其他事情,并允许Cython代码使用多个内核(还有其他工作)。
Cython可以使用Python类型提示语法
Python具有类型提示语法 ,主要由短绒和代码检查器使用,而不是CPython解释器使用。 Cython具有自己的代码修饰自定义语法,但是在Cython的最新版本中,您还可以使用Python类型提示语法为Cython提供基本的类型提示。
Cython可用于遮盖敏感的Python代码
Python模块非常容易反编译和检查,但编译后的二进制文件却并非如此。 在将Python应用程序分发给最终用户时,如果要保护其某些模块不受偶然监听,可以通过使用Cython进行编译来实现。 但是请注意,这是用Cython的能力,它的预期功能而不是一个副作用 。
Cython局限性
请记住,Cython不是魔杖。 它不会自动将所有棘手的Python代码实例转换为快速的C代码。 要充分利用Cython,您必须明智地使用它并了解其局限性:
传统Python代码几乎没有加速
当Cython遇到Python代码时,它无法完全转换为C,它将代码转换为对Python内部的一系列C调用。 这相当于将Python的解释器带出了执行循环,默认情况下,该解释器使代码适度提高15%到20%。 注意,这是最佳情况。 在某些情况下,您可能看不到性能改善甚至性能下降。
原生Python数据结构的加速很少
Python提供了许多数据结构-字符串,列表,元组,字典等。 它们为开发人员提供了极大的便利,并且具有自己的自动内存管理功能。 但是它们比纯C慢。
Cython允许您继续使用所有Python数据结构,尽管速度没有太大提高。 同样,这是因为Cython只是在Python运行时中调用创建和操作这些对象的C API。 因此,Python数据结构的行为通常类似于经过Cython优化的Python代码:您有时会得到提升,但只有一点点提升。 为了获得最佳结果,请使用C变量和结构。 好消息是Cython使与他们的合作变得容易。
Cython代码在“纯C”时运行最快
如果您在C中有一个标有cdef
关键字的函数,并且其所有变量和对纯C的其他事物的内联函数调用都将以C可以运行的速度运行。 但是,如果该函数引用任何Python本地代码,例如Python数据结构或对内部Python API的调用,则该调用将成为性能瓶颈。
幸运的是,Cython提供了一种发现这些瓶颈的方法: 源代码报告可一目了然地显示您的Cython应用程序的哪些部分是纯C语言,哪些部分与Python交互。 优化应用程序越好,与Python的交互越少。
Cython NumPy
Cython改进了基于C的第三方数字运算库(如NumPy)的使用。 由于Cython代码可编译为C,因此可以直接与这些库进行交互,从而消除了Python的瓶颈。
但是NumPy特别适合Cython。 Cython对NumPy中的特定结构具有本地支持,并提供对NumPy阵列的快速访问。 Cython可以按原样在常规Python脚本中使用相同的NumPy语法。
但是,如果要在Cython和NumPy之间创建最接近的绑定,则需要使用Cython的自定义语法进一步修饰代码。 例如, cimport
语句允许Cython代码在编译时查看库中的C级结构,以实现尽可能最快的绑定。
由于NumPy的使用如此广泛,因此Cython可以“开箱即用”地支持NumPy 。 如果已安装NumPy,则只需在代码中声明cimport numpy
,然后添加其他修饰即可使用公开的功能。
Cython分析和性能
通过对任何代码进行概要分析并亲眼看到瓶颈所在,可以从任何代码中获得最佳性能。 Cython 为Python的cProfile模块提供了钩子 ,因此您可以使用Python自己的概要分析工具(例如cProfile )来查看Cython代码的性能。
在所有情况下都有助于记住Cython并不是魔术,明智的现实性能实践仍然适用。 您在Python和Cython之间来回穿梭的次数越少,应用程序运行的速度就越快。
例如,如果您有一个要在Cython中处理的对象的集合,则不要在Python中对其进行迭代并在每个步骤都调用Cython函数。 将整个集合传递到您的Cython模块并在那里进行迭代。 该技术通常用于管理数据的库中,因此它是在您自己的代码中进行仿真的一个很好的模型。
我们之所以使用Python,是因为它为程序员提供了便利,并支持快速开发。 有时程序员的生产力是以性能为代价的。 使用Cython,只需付出一点点额外的努力就可以使您两全其美。
进一步了解Python
- 什么是Python? 强大,直观的编程
- 什么是PyPy? 更快的Python而无痛苦
- 什么是赛顿? Python以C的速度
- Cython教程:如何加速Python
- 如何聪明地安装Python
- Python 3.8中最好的新功能
- 通过Poetry更好的Python项目管理
- Virtualenv和venv:解释了Python虚拟环境
- Python virtualenv和venv做和不做
- Python线程和子流程说明
- 如何使用Python调试器
- 如何使用timeit来分析Python代码
- 如何使用cProfile来分析Python代码
- 开始使用Python进行异步处理
- 如何在Python中使用asyncio
- 如何将Python转换为JavaScript(然后再次转换)
- Python 2 EOL:如何在Python 2结束后生存
- 每种编程需要12个Python
- 每个Python开发人员都有24个Python库
- 您可能会错过的7个出色的Python IDE
- Python的3个主要缺点及其解决方案
- 比较了13个Python Web框架
- 4个Python测试框架可消除您的错误
- 6个您不想错过的Python新功能
- 5种用于掌握机器学习的Python发行版
- 8个出色的Python库用于自然语言处理
From: https://www.infoworld.com/article/3250299/what-is-cython-python-at-the-speed-of-c.html
什么是赛顿? Python以C的速度相关推荐
- Python学习之解决python下载第三方依赖速度慢的问题
Python学习之解决python下载第三方依赖速度慢的问题 参考文章: (1)Python学习之解决python下载第三方依赖速度慢的问题 (2)https://www.cnblogs.com/su ...
- 解决PyCharm下载Python第三方库时速度慢的问题
解决PyCharm下载Python第三方库时速度慢的问题 最近在PyCharm环境下下载Python包时频繁遇到time out类型的问题,现将解决方法描述如下: 打开Pycharm,点击File - ...
- 关于python安装第三方库速度慢解决方案(opencv为例)
关于python安装第三方库速度慢解决方案(opencv为例) 参考文章: (1)关于python安装第三方库速度慢解决方案(opencv为例) (2)https://www.cnblogs.com/ ...
- python那么慢为什么还有人用-为什么大家都说python编程的效率速度慢呢?
今天的python培训想和大家分享一下python编程语言慢的原因,让大家采取一些措施避免其缺陷,希望对大家有所帮助! 近年来Python语言开始流行.它广泛应用于网络开发和运营.数据科学.网络开发和 ...
- python的最大绘图速度_Python数据可视化之高速绘图神器PyQtGraph库,强烈建议收藏...
01为什么使用PyQtGraph库 我们知道,在Python中,已经有了很多可供选择的数据可视化库. 比如最经典.使用人数最多的matplotlib库,其有着十多年的历史积累,可生成高质量出版级别的图 ...
- python小技巧及速度提高-python编码时有什么技巧可以提升速度?
可加速你的Python应用程序. 1.让关键代码依赖于外部包 虽然Python让许多编程任务变得容易,但它可能并不总能为紧急的任务提供最佳性能.你可以为紧急的任务使用C.C++或机器语言编写的外部包, ...
- python矩阵赋值提高速度_Numpy大规模矩阵运算优化加速技巧
如果对数组进行向量化运算,例如全体四则运算.矩阵乘法.求和.按指标求和等,一定要利用numpy的矩阵乘法dot和einsum. dot 二维矩阵乘法 numpy的矩阵运算的王牌,做矩阵乘法的首选,优化 ...
- python提高导入数据库速度_提高从MongoDB导入数据速度
Python编写爬虫,用的是Scrapy框架,将数据存储到了本机的MongoDB数据库上.导数据的时候发现数据的转化,速度有点慢. from pymongo import MongoClient #建 ...
- python matlab 速度_关于python:MATLAB的速度是Numpy的两倍
我是一名工程学研究生,目前出于数值模拟的目的,正在从MATLAB过渡到Python.我的印象是,对于基本的数组操作,Numpy将与MATLAB一样快.但是,对于我编写的两个不同程序,MATLAB的运行 ...
最新文章
- 面试题31.连续子数组的最大和
- lua如何打印行号_Lua 字符串处理
- python的0基础入门语法_学习小结(1)
- oracle优质图书,经典Oracle图书推荐(之四)_oracle
- 特征提取、特征描述、特征匹配的通俗解释
- 【转】Mac下升级python2.7到python3.6
- 搬水果 - 九度教程第31题(哈夫曼树)
- oracle视频教程11g入门运维DBA性能优化OCP培训SQL数据库在线课程
- 凯撒密码及C语言python实现
- win10多合一原版系统_【教程】制作Windows 10 多合一原版系统
- 局域网传文件_秒杀QQ微信,这3个神器传输文件快10倍
- 用计算机怎么管理小米路由器,如何为小米路由器设置局域网
- 毕业论文中的参考文献怎么引用?
- python查火车票_Python查询火车票(三)
- cp:略过目录:”文件名“
- C# 从零开始写 SharpDx 应用 画三角
- VScode全大写快捷键_iPad OS 键盘鼠标深度体验,最全快捷键整理。
- 查看exe和dll等二进制文件时间戳(生成时间)的工具与方法介绍
- 数据通信,数据通信原理是什么?
- 江苏省计算机二级c语言考试范围,江苏省计算机二级C语言考试大纲.doc