能让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语言技巧之三元运算符使用介绍
Mar 04 Python
Python-基础-入门 简介
Aug 09 Python
跟老齐学Python之复习if语句
Oct 02 Python
栈和队列数据结构的基本概念及其相关的Python实现
Aug 24 Python
Python的mysql数据库的更新如何实现
Jul 31 Python
Python实现matplotlib显示中文的方法详解
Feb 06 Python
pandas DataFrame 交集并集补集的实现
Jun 24 Python
python用requests实现http请求代码实例
Oct 31 Python
pandas数据选取:df[] df.loc[] df.iloc[] df.ix[] df.at[] df.iat[]
Apr 24 Python
Python实现清理微信僵尸粉功能示例【基于itchat模块】
May 29 Python
Python自定义sorted排序实现方法详解
Sep 18 Python
Python加载数据的5种不同方式(收藏)
Nov 13 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
PHP 开源AJAX框架14种
2009/08/24 PHP
thinkphp中memcache的用法实例
2014/11/29 PHP
ZendFramework2连接数据库操作实例
2017/04/18 PHP
laravel dingo API返回自定义错误信息的实例
2019/09/29 PHP
数据结构之利用PHP实现二分搜索树
2020/10/25 PHP
js removeChild 障眼法 可能出现的错误
2009/10/06 Javascript
ExtJS如何设置与获取radio控件的选取状态
2014/01/22 Javascript
JavaScript代码应该放在HTML代码哪个位置比较好?
2014/10/16 Javascript
jQuery表单域属性过滤器用法分析
2015/02/10 Javascript
跟我学习javascript的prototype原型和原型链
2015/11/18 Javascript
基于javascript实现图片预加载
2016/01/05 Javascript
一款简单的jQuery图片标注效果附源码下载
2016/03/22 Javascript
jQuery实现内容定时切换效果完整实例
2016/04/06 Javascript
ECMAScript6快速入手攻略
2016/07/18 Javascript
JS获取一个表单字段中多条数据并转化为json格式
2017/10/17 Javascript
Angular如何在应用初始化时运行代码详解
2018/06/11 Javascript
JavaScript的Object.defineProperty详解
2018/07/09 Javascript
使用Karma做vue组件单元测试的实现
2020/01/16 Javascript
微信小程序国际化探索实现(附源码地址)
2020/05/20 Javascript
[03:37]2014DOTA2国际邀请赛 主赛事第一日胜者组TOPPLAY
2014/07/19 DOTA
详细介绍Python中的偏函数
2015/04/27 Python
Python datetime和unix时间戳之间相互转换的讲解
2019/04/01 Python
python数据预处理方式 :数据降维
2020/02/24 Python
python GUI库图形界面开发之PyQt5窗口布局控件QStackedWidget详细使用方法
2020/02/27 Python
Pycharm最常用的快捷键及使用技巧
2020/03/05 Python
Python爬取12306车次信息代码详解
2020/08/12 Python
五分钟带你搞懂python 迭代器与生成器
2020/08/30 Python
css3 box-shadow阴影(外阴影与外发光)图示讲解
2017/08/11 HTML / CSS
小学优秀班主任事迹材料
2014/05/17 职场文书
法制教育演讲稿
2014/09/10 职场文书
2015年个人实习工作总结
2014/12/12 职场文书
挂职锻炼个人总结
2015/03/05 职场文书
个人总结格式范文
2015/03/09 职场文书
2016秋季幼儿园开学寄语
2015/12/03 职场文书
2016感恩母亲节校园广播稿
2015/12/17 职场文书
Apache SeaTunnel实现 非CDC数据抽取
2022/05/20 Servers