能让Python提速超40倍的神器Cython详解


Posted in Python onJune 24, 2021

让Python提速超过40倍的神器:Cython

人工智能最火的语言,自然是被誉为迄今为止最容易使用的代码之一的Python。Python代码素来以直观、高可读性著称。

然而,易用的背后,是Python无法逾越的障碍:慢。尤其是C程序员,这群快枪手简直无法忍受Python的慢。

所以有人就想了各种方法去解决这个问题,本文就介绍其中的一种。如果你的代码是纯Python,或者你必须用一个大的for循环却无法放入矩阵因为数据必须按顺序处理,那么就可以使用Cython来加速Python。

1、什么是Cython?

根据维基百科:Cython是结合了Python和C的语法的一种语言,可以简单的认为就是给Python加上了静态类型后的语法,使用者可以维持大部分的Python语法,而不需要大幅度调整主要的程式逻辑与算法。但由于会直接编译为二进制程序,所以性能较Python会有很大提升。

Cython被大量运用在CPython函式库的撰写,以取得较高的执行效能。Cython将CPython代码转译成 C 或 C++ 语法后,自动包装上函式呼叫界面生成 .pyx 后缀的执行档,即可当成普通的函式库。其性能一般逊于原生的 C/C++ 函式库,但由于 CPython 语法的易用性可以缩短开发时间。Cython 也可以用于编译以 C/C++ 为 CPython 撰写的函式库。

目前Cython可以在 Windows, macOS 与 Linux 上使用,可以编译 2.6, 2.7 与 3.3 至 3.7 版本的 CPython 语法。

我们对Python代码的唯一调整是向每个变量添加类型信息。通常,我们可以在Python中声明一个变量,如下所示:

x = 0.5

使用Cython,我们将为该变量添加一个类型:

cdef float x = 0.5

这告诉Cython我们的变量是浮点数,和C一样。使用纯Python,变量的类型是动态确定的。Cython中类型的显式声明是可以转换为C的原因,因为需要显式类型声明+。

安装Cython只需要一行pip:

pip install cython

2、Cython的类型

使用Cython时,有两种不同的类型,用于变量和函数。

对于变量,我们有:

cdef int a, b, c
cdef char *s
cdef float x = 0.5 (single precision)
cdef double x = 63.4 (double precision)
cdef list names
cdef dict goals_for_each_play
cdef object card_deck

请注意所有这些类型都来自C/C++! 

对于功能:

def — regular python function, calls from Python only.
cdef — Cython only functions which can't be accessed from python-only code i.e must be called within Cython
cpdef — C and Python. Can be accessed from both C and Python

由此开始,我们要开启加速了哦!准备好…

3、使用Cython加速代码

我们要做的第一件事就是设置Python代码基准:用于计算数字阶乘的for循环。 

原始Python代码如下所示:

def test(x):

  y = 1

  for i in range(x+1):

    y *= i

  return y

Cython相同功能看起来非常相似。确保Cython代码文件使用 .pyx扩展名。代码本身的唯一变化是我们需要提前声明变量和函数的类型,示例代码如下:

cpdef int test(int x):

    cdef int y = 1

    cdef int i

    for i in range(x+1):

        y *= i

    return y

注意函数有一个cpdef来确保我们可以从Python调用它。另外还需要为函数中的所有变量设置类型从而告知C编译器。

接下来,创建一个setup.py文件,该文件将Cython代码编译为C代码:

from distutils.core import setup
from Cython.Build import cythonize
setup(ext_modules = cythonize('run_cython.pyx'))

并执行编译:

python setup.py build_ext --inplace

搞定!我们的C代码已经编译好并且可以使用了。

在Cython代码所在的文件夹中拥有运行C代码所需的所有文件,包括run_cython.c文件,你尽可以进去仔细看个究竟。

现在,我们要测试全新超快速C代码了!准备好了吗?3、2、1、go!

import run_python
import run_cython
import time
 
 
number = 10
 
 
start = time.time()
run_python.test(number)
end =  time.time()
 
py_time = end - start
print("Python time = {}".format(py_time))
 
start = time.time()
run_cython.test(number)
end =  time.time()
 
cy_time = end - start
print("Cython time = {}".format(cy_time))
 
 
print("Speedup = {}".format(py_time / cy_time))

Cython几乎可以为任何原始Python代码提供良好的加速,不需要做太多额外的工作。记住,你用的循环越多、处理的数据越多,Cython就越有帮助。

看看下表,其中显示了Cython为不同的阶乘值提供了多少速度。我们使用Cython获得了超过36倍的加速!

能让Python提速超40倍的神器Cython详解

到此这篇关于能让Python提速超40倍的神器Cython详解的文章就介绍到这了,更多相关Cython加速Python内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python中将阿拉伯数字转换成中文的实现代码
May 19 Python
Python多线程编程(七):使用Condition实现复杂同步
Apr 05 Python
django+js+ajax实现刷新页面的方法
May 22 Python
python 实现二维列表转置
Dec 02 Python
python matplotlib画盒图、子图解决坐标轴标签重叠的问题
Jan 19 Python
Django import export实现数据库导入导出方式
Apr 03 Python
Python新手学习函数默认参数设置
Jun 03 Python
Python collections.deque双边队列原理详解
Oct 05 Python
Python在centos7.6上安装python3.9的详细教程(默认python版本为2.7.5)
Oct 15 Python
用python查找统一局域网下ip对应的mac地址
Jan 13 Python
python如何发送带有附件、正文为HTML的邮件
Feb 27 Python
python的netCDF4批量处理NC格式文件的操作方法
Mar 21 Python
FP-growth算法发现频繁项集——构建FP树
python ansible自动化运维工具执行流程
关于python中readlines函数的参数hint的相关知识总结
详解Python为什么不用设计模式
linux中nohup和后台运行进程查看及终止
Jun 24 #Python
Python面向对象之成员相关知识总结
Jun 24 #Python
Python面向对象之内置函数相关知识总结
Jun 24 #Python
You might like
用文本文件制作留言板提示(下)
2006/10/09 PHP
第4章 数据处理-php数组的处理-郑阿奇
2011/07/04 PHP
php写的带缓存数据功能的mysqli类
2012/09/06 PHP
PHP英文字母大小写转换函数小结
2014/05/03 PHP
php实例分享之html转为rtf格式
2014/06/02 PHP
分享10段PHP常用代码
2015/11/11 PHP
Javascript 代码也可以变得优美的实现方法
2009/06/22 Javascript
Array.prototype.slice 使用扩展
2010/06/09 Javascript
js实时监听文本框状态的方法
2011/04/26 Javascript
自己实现string的substring方法 人民币小写转大写,数字反转,正则优化
2012/09/02 Javascript
jQuery性能优化28条建议你值得借鉴
2013/02/16 Javascript
九种js弹出对话框的方法总结
2013/03/12 Javascript
JavaScript实现生成GUID(全局统一标识符)
2014/09/05 Javascript
jQuery实现提示密码强度的代码
2015/07/15 Javascript
JavaScript保留关键字汇总
2015/12/01 Javascript
JS从一组数据中找到指定的单条数据的方法
2016/06/02 Javascript
基于vue+canvas的excel-like组件实例详解
2017/11/28 Javascript
使用npm安装最新版本nodejs
2018/01/18 NodeJs
vue props传值失败 输出undefined的解决方法
2018/09/11 Javascript
js根据需要计算数组中重复出现某个元素的个数
2019/01/18 Javascript
[02:05]2014DOTA2西雅图国际邀请赛 BBC第二天小组赛总结
2014/07/11 DOTA
[03:22]DAC最前线(第二期)—DOTA2亚洲邀请赛主赛场周边及线路探访
2015/01/24 DOTA
python实现根据窗口标题调用窗口的方法
2015/03/13 Python
在Python中使用列表生成式的教程
2015/04/27 Python
python获取外网ip地址的方法总结
2015/07/02 Python
Python实现的多线程http压力测试代码
2017/02/08 Python
python通过matplotlib生成复合饼图
2020/02/06 Python
基于FME使用Python过程图解
2020/05/13 Python
佳能德国网上商店:Canon德国
2017/03/18 全球购物
80年代复古T恤:TruffleShuffle
2018/07/02 全球购物
写演讲稿要注意的六件事
2014/01/14 职场文书
九年级家长会邀请函
2014/01/15 职场文书
军训自我鉴定怎么写
2014/02/13 职场文书
黄金酒广告词
2014/03/21 职场文书
祖国在我心中演讲稿300字
2014/05/04 职场文书
Golang中异常处理机制详解
2021/06/08 Golang