能让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读取TXT到数组及列表去重后按原来顺序排序的方法
Jun 26 Python
python主线程捕获子线程的方法
Jun 17 Python
利用python实现对web服务器的目录探测的方法
Feb 26 Python
Python统计一个字符串中每个字符出现了多少次的方法【字符串转换为列表再统计】
May 05 Python
pyqt5 使用cv2 显示图片,摄像头的实例
Jun 27 Python
python在新的图片窗口显示图片(图像)的方法
Jul 11 Python
Python 离线工作环境搭建的方法步骤
Jul 29 Python
使用Python快乐学数学Github万星神器Manim简介
Aug 07 Python
python 实现方阵的对角线遍历示例
Nov 29 Python
opencv 图像腐蚀和图像膨胀的实现
Jul 07 Python
浅谈matplotlib 绘制梯度下降求解过程
Jul 12 Python
python 数据类型强制转换的总结
Jan 25 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实现的网络相册图片防盗链完美破解方法
2015/07/01 PHP
谈谈从phpinfo中能获取哪些值得注意的信息
2017/03/28 PHP
PHP判断一个变量是否为整数、正整数的方法示例
2019/09/11 PHP
多浏览器兼容的获取元素和鼠标的位置的js代码
2009/12/15 Javascript
在jQuery 1.5中使用deferred对象的代码(翻译)
2011/03/10 Javascript
JS下拉缓冲菜单示例代码
2013/08/30 Javascript
JavaScript 垃圾回收机制分析
2013/10/10 Javascript
javascript间隔定时器(延时定时器)学习 间隔调用和延时调用
2014/01/13 Javascript
js使用ajax读博客rss示例
2014/05/06 Javascript
JS 获取鼠标左右键的键值方法
2014/10/11 Javascript
javascript使用for循环批量注册的事件不能正确获取索引值的解决方法
2014/12/20 Javascript
js验证真实姓名与身份证号,手机号的简单实例
2016/07/18 Javascript
javascript判断firebug是否开启的方法
2016/11/23 Javascript
JavaScript异步加载问题总结
2018/02/17 Javascript
js循环map 获取所有的key和value的实现代码(json)
2018/05/09 Javascript
Vue作用域插槽slot-scope实例代码
2018/09/05 Javascript
Vue中使用ElementUI使用第三方图标库iconfont的示例
2018/10/11 Javascript
vue中进行微博分享的实例讲解
2019/10/14 Javascript
ES6箭头函数和扩展实例分析
2020/05/23 Javascript
vc6编写python扩展的方法分享
2014/01/17 Python
在python3.5中使用OpenCV的实例讲解
2018/04/02 Python
详解tensorflow载入数据的三种方式
2018/04/24 Python
详解python使用turtle库来画一朵花
2019/03/21 Python
PyQt 实现使窗口中的元素跟随窗口大小的变化而变化
2019/06/18 Python
python中struct模块之字节型数据的处理方法
2019/08/27 Python
Python箱型图绘制与特征值获取过程解析
2019/10/22 Python
python批量修改xml属性的实现方式
2020/03/05 Python
HTML5 自动聚焦(autofocus)属性使用介绍
2013/08/07 HTML / CSS
Oracle快照(snapshot)
2015/03/13 面试题
EJB的基本架构
2016/09/22 面试题
总经理秘书的岗位职责
2013/12/27 职场文书
银行演讲稿范文
2014/01/03 职场文书
浅谈Python中的函数(def)及参数传递操作
2021/05/25 Python
详解Python中的进程和线程
2021/06/23 Python
AngularJS实现多级下拉框
2022/03/25 Javascript
Golang Elasticsearches 批量修改查询及发送MQ
2022/04/19 Golang