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

如果我们为函数参数和函数主体中使用的变量( doubleint等) 明确声明变量类型 ,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的交互越少。

IDG

为Cython应用程序生成的源代码报告。 白色区域为纯C区域; 黄色区域显示与Python内部的交互。 经过充分优化的Cython程序将具有尽可能少的黄色。 扩展后的最后一行显示了其对应的Cython代码下的C代码。

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的速度相关推荐

  1. Python学习之解决python下载第三方依赖速度慢的问题

    Python学习之解决python下载第三方依赖速度慢的问题 参考文章: (1)Python学习之解决python下载第三方依赖速度慢的问题 (2)https://www.cnblogs.com/su ...

  2. 解决PyCharm下载Python第三方库时速度慢的问题

    解决PyCharm下载Python第三方库时速度慢的问题 最近在PyCharm环境下下载Python包时频繁遇到time out类型的问题,现将解决方法描述如下: 打开Pycharm,点击File - ...

  3. 关于python安装第三方库速度慢解决方案(opencv为例)

    关于python安装第三方库速度慢解决方案(opencv为例) 参考文章: (1)关于python安装第三方库速度慢解决方案(opencv为例) (2)https://www.cnblogs.com/ ...

  4. python那么慢为什么还有人用-为什么大家都说python编程的效率速度慢呢?

    今天的python培训想和大家分享一下python编程语言慢的原因,让大家采取一些措施避免其缺陷,希望对大家有所帮助! 近年来Python语言开始流行.它广泛应用于网络开发和运营.数据科学.网络开发和 ...

  5. python的最大绘图速度_Python数据可视化之高速绘图神器PyQtGraph库,强烈建议收藏...

    01为什么使用PyQtGraph库 我们知道,在Python中,已经有了很多可供选择的数据可视化库. 比如最经典.使用人数最多的matplotlib库,其有着十多年的历史积累,可生成高质量出版级别的图 ...

  6. python小技巧及速度提高-python编码时有什么技巧可以提升速度?

    可加速你的Python应用程序. 1.让关键代码依赖于外部包 虽然Python让许多编程任务变得容易,但它可能并不总能为紧急的任务提供最佳性能.你可以为紧急的任务使用C.C++或机器语言编写的外部包, ...

  7. python矩阵赋值提高速度_Numpy大规模矩阵运算优化加速技巧

    如果对数组进行向量化运算,例如全体四则运算.矩阵乘法.求和.按指标求和等,一定要利用numpy的矩阵乘法dot和einsum. dot 二维矩阵乘法 numpy的矩阵运算的王牌,做矩阵乘法的首选,优化 ...

  8. python提高导入数据库速度_提高从MongoDB导入数据速度

    Python编写爬虫,用的是Scrapy框架,将数据存储到了本机的MongoDB数据库上.导数据的时候发现数据的转化,速度有点慢. from pymongo import MongoClient #建 ...

  9. python matlab 速度_关于python:MATLAB的速度是Numpy的两倍

    我是一名工程学研究生,目前出于数值模拟的目的,正在从MATLAB过渡到Python.我的印象是,对于基本的数组操作,Numpy将与MATLAB一样快.但是,对于我编写的两个不同程序,MATLAB的运行 ...

最新文章

  1. 面试题31.连续子数组的最大和
  2. lua如何打印行号_Lua 字符串处理
  3. python的0基础入门语法_学习小结(1)
  4. oracle优质图书,经典Oracle图书推荐(之四)_oracle
  5. 特征提取、特征描述、特征匹配的通俗解释
  6. 【转】Mac下升级python2.7到python3.6
  7. 搬水果 - 九度教程第31题(哈夫曼树)
  8. oracle视频教程11g入门运维DBA性能优化OCP培训SQL数据库在线课程
  9. 凯撒密码及C语言python实现
  10. win10多合一原版系统_【教程】制作Windows 10 多合一原版系统
  11. 局域网传文件_秒杀QQ微信,这3个神器传输文件快10倍
  12. 用计算机怎么管理小米路由器,如何为小米路由器设置局域网
  13. 毕业论文中的参考文献怎么引用?
  14. python查火车票_Python查询火车票(三)
  15. cp:略过目录:”文件名“
  16. C# 从零开始写 SharpDx 应用 画三角
  17. VScode全大写快捷键_iPad OS 键盘鼠标深度体验,最全快捷键整理。
  18. 查看exe和dll等二进制文件时间戳(生成时间)的工具与方法介绍
  19. 数据通信,数据通信原理是什么?
  20. 江苏省计算机二级c语言考试范围,江苏省计算机二级C语言考试大纲.doc

热门文章

  1. 韩信点兵算法——c语言实现
  2. java面向过程外卖订餐系统 完整版
  3. 【已解决】Jena配置问题
  4. php获取url中的参数
  5. 窗口置顶工具v2.4.0
  6. 学习笔记(01):大数据视频_Hive视频教程(上)-Hive安装_其他操作命令
  7. 《Python网络爬虫从入门到实践 第2版》第15章 爬虫实践二:知乎Live
  8. 盐酸除铁方法 盐酸除铁树脂 盐酸里面的铁怎么去除
  9. 【权威】等级保护和分级保护
  10. 无锡设计培训——平面设计师都学什么