详解如何利用Cython为Python代码加速


Posted in Python onJanuary 27, 2018

引言

通常,在 Python 中写循环(特别是多重循环)非常的慢,在文章 https://3water.com/article/133807.htm中,我们的元胞自动机的状态更新函数 update_state 使用了两重循环,所以我们尝试用 Cython 重构该方法。

代码

我们在同文件夹下新建一个 update.pyx 文件,写入如下内容

import numpy as np 
cimport numpy as np 
cimport cython


DTYPE = np.float
ctypedef np.float_t DTYPE_t

def update_state(np.ndarray[DTYPE_t, ndim=2] cells):
  return update_state_c(cells)

@cython.boundscheck(False)
@cython.wraparound(False)
cdef np.ndarray[DTYPE_t, ndim=2] update_state_c(np.ndarray[DTYPE_t, ndim=2] cells):
  """更新一次状态"""
  cdef unsigned int i
  cdef unsigned int j

  cdef np.ndarray[DTYPE_t, ndim=2] buf = np.zeros((cells.shape[0], cells.shape[1]), dtype=DTYPE)
  cdef DTYPE_t neighbor_num
  for i in range(1, cells.shape[0] - 1):
    for j in range(1, cells.shape[0] - 1):
      # 计算该细胞周围的存活细胞数
      
      neighbor_num = cells[i, j-1] + cells[i, j+1] + cells[i+1, j] + cells[i-1, j] +\
              cells[i-1, j-1] + cells[i-1, j+1] +\
              cells[i+1, j-1] + cells[i+1, j+1]
      
      if neighbor_num == 3:
        buf[i, j] = 1
      elif neighbor_num == 2:
        buf[i, j] = cells[i, j]
      else:
        buf[i, j] = 0
  return buf

update_state_c 函数上的两个装饰器是用来关闭 Cython 的边界检查的。

在同文件下新建一个 setup.py 文件

import numpy as np
from distutils.core import setup
from Cython.Build import cythonize

setup(
  name="Cython Update State",
  ext_modules=cythonize("update.pyx"),
  include_dirs=[np.get_include()]
)

因为在 Cython 文件中使用了 NumPy 的头文件,所以我们需要在 setup.py 将其包含进去。

执行 python setup.py build_ext --inplace 后,同文件夹下会生成一个 update.cp36-win_amd64.pyd 的文件,这就是编译好的 C 扩展。

我们修改原始的代码,首先在文件头部加入 import update as cupdate,然后修改更新方法如下

def update_state(self):
  """更新一次状态"""
  self.cells = cupdate.update_state(self.cells)
  self.timer += 1

将原方法名就改为 update_state_py 即可,运行脚本,无异常。

测速

我们编写一个方法来测试一下使用 Cython 可以带来多少速度的提升

def test_time():
  import time
  game = GameOfLife(cells_shape=(60, 60))
  t1 = time.time()
  for _ in range(300):
    game.update_state()
  t2 = time.time()
  print("Cython Use Time:", t2 - t1)
  del game
  game = GameOfLife(cells_shape=(60, 60))
  t1 = time.time()
  for _ in range(300):
    game.update_state_py()
  t2 = time.time()
  print("Native Python Use Time:", t2 - t1)

运行该方法,在我的电脑上输出如下

Cython Use Time: 0.007000446319580078
Native Python Use Time: 4.342248439788818

速度提升了 600 多倍。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python获取远程图片大小和尺寸的方法
Mar 26 Python
玩转python selenium鼠标键盘操作(ActionChains)
Apr 12 Python
深入浅析Python 中 is 语法带来的误解
May 07 Python
Django 模型类(models.py)的定义详解
Jul 19 Python
python读取大文件越来越慢的原因与解决
Aug 08 Python
Python网络编程之使用TCP方式传输文件操作示例
Nov 01 Python
matplotlib实现显示伪彩色图像及色度条
Dec 07 Python
计算pytorch标准化(Normalize)所需要数据集的均值和方差实例
Jan 15 Python
Tensorflow中tf.ConfigProto()的用法详解
Feb 06 Python
python设置环境变量的作用整理
Feb 17 Python
python 利用jieba.analyse进行 关键词提取
Dec 17 Python
python 基于pygame实现俄罗斯方块
Mar 02 Python
详解Python 实现元胞自动机中的生命游戏(Game of life)
Jan 27 #Python
Python实现的栈(Stack)
Jan 26 #Python
使用python实现链表操作
Jan 26 #Python
Python中optparser库用法实例详解
Jan 26 #Python
python利用socketserver实现并发套接字功能
Jan 26 #Python
Django的HttpRequest和HttpResponse对象详解
Jan 26 #Python
Python编程实现的简单神经网络算法示例
Jan 26 #Python
You might like
深入解析php中的foreach函数
2013/08/31 PHP
php中有关合并某一字段键值相同的数组合并的改进
2015/03/10 PHP
PHP 微信支付类 demo
2015/11/30 PHP
两个比较有用的Javascript工具函数代码
2010/02/17 Javascript
JS 如何获取radio选中后的值及不选择取radio的值
2013/10/28 Javascript
使用javascript实现判断当前浏览器
2015/04/14 Javascript
javascript实现类似百度分享功能的方法
2015/07/27 Javascript
纯JS代码实现气泡效果
2016/05/04 Javascript
JS中使用DOM来控制HTML元素
2016/07/31 Javascript
jQuery实现点击任意位置弹出层外关闭弹出层效果
2016/10/19 Javascript
jQuery实现的页面弹幕效果【测试可用】
2018/08/17 jQuery
如何正确理解vue中的key详解
2019/11/02 Javascript
python中遍历文件的3个方法
2014/09/02 Python
python3生成随机数实例
2014/10/20 Python
Python中的作用域规则详解
2015/01/30 Python
Python3连接MySQL(pymysql)模拟转账实现代码
2016/05/24 Python
深入浅出分析Python装饰器用法
2017/07/28 Python
用Eclipse写python程序
2018/02/10 Python
python matplotlib绘图,修改坐标轴刻度为文字的实例
2018/05/25 Python
python实现数据清洗(缺失值与异常值处理)
2019/12/02 Python
Python zip函数打包元素实例解析
2019/12/11 Python
python读取mysql数据绘制条形图
2020/03/25 Python
在服务器上安装python3.8.2环境的教程详解
2020/04/26 Python
python音频处理的示例详解
2020/12/23 Python
用纯CSS3实现网页中常见的小箭头
2017/10/16 HTML / CSS
花园仓库建筑:Garden Buildings Direct
2018/02/16 全球购物
社区母亲节活动记录
2014/03/06 职场文书
幼儿园家长寄语
2014/04/02 职场文书
应届生自荐书
2014/06/23 职场文书
伏羲庙导游词
2015/02/09 职场文书
使用pipenv管理python虚拟环境的全过程
2021/09/25 Python
Html5获取用户当前位置的几种方式
2022/01/18 HTML / CSS
Python语言内置数据类型
2022/02/24 Python
海贼王十大逆天果实 魂魂果实上榜,岩浆果实攻击力最强
2022/03/18 日漫
html中相对位置与绝对位置的具体使用
2022/05/15 HTML / CSS
Java使用HttpClient实现文件下载
2022/08/14 Java/Android