详解如何利用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中的hashlib和base64加密模块使用实例
Sep 02 Python
python每隔N秒运行指定函数的方法
Mar 16 Python
python写入中英文字符串到文件的方法
May 06 Python
利用Python循环(包括while&for)各种打印九九乘法表的实例
Nov 06 Python
为什么入门大数据选择Python而不是Java?
Mar 07 Python
在NumPy中创建空数组/矩阵的方法
Jun 15 Python
基于Python列表解析(列表推导式)
Jun 23 Python
对python opencv 添加文字 cv2.putText 的各参数介绍
Dec 05 Python
Python设计模式之观察者模式原理与用法详解
Jan 16 Python
Python实现AI自动抠图实例解析
Mar 05 Python
python实现每天自动签到领积分的示例代码
Aug 18 Python
Python函数式编程中itertools模块详解
Sep 15 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中在数据库中保存Checkbox数据(2)
2006/10/09 PHP
BBS(php & mysql)完整版(一)
2006/10/09 PHP
php中数组首字符过滤功能代码
2012/07/31 PHP
ThinkPHP访问不存在的模块跳转到404页面的方法
2014/06/19 PHP
PHP的全局错误处理详解
2016/04/25 PHP
PHP实现上传多文件示例代码
2017/02/20 PHP
一些常用的JS功能函数(2009-06-04更新)
2009/06/04 Javascript
jQuery TextBox自动完成条
2009/07/22 Javascript
用JQuery调用Session的实现代码
2010/10/29 Javascript
js 如何实现对数据库的增删改查
2012/11/23 Javascript
js中split函数的使用方法说明
2013/12/26 Javascript
jQuery的remove()方法使用详解
2015/08/11 Javascript
jQuery+PHP+MySQL实现无限级联下拉框效果
2016/02/19 Javascript
第一篇初识bootstrap
2016/06/21 Javascript
微信小程序 实现点击添加移除class
2017/06/12 Javascript
基于vue.js路由参数的实例讲解——简单易懂
2017/09/07 Javascript
详解从vue-loader源码分析CSS Scoped的实现
2019/09/23 Javascript
Vue快速实现通用表单验证的方法
2020/02/24 Javascript
使用Python操作Elasticsearch数据索引的教程
2015/04/08 Python
使用Django的模版来配合字符串翻译工作
2015/07/27 Python
在Python的Flask框架中验证注册用户的Email的方法
2015/09/02 Python
python通过opencv实现批量剪切图片
2017/11/13 Python
详解python实现数据归一化处理的方式:(0,1)标准化
2019/07/17 Python
Python获取时间范围内日期列表和周列表的函数
2019/08/05 Python
使用python快速在局域网内搭建http传输文件服务的方法
2019/11/14 Python
Ralph Lauren英国官方网站:Ralph Lauren UK
2018/04/03 全球购物
英国现代家具和装饰网站:PN Home
2018/08/16 全球购物
心理学专业毕业生推荐信范文
2013/11/21 职场文书
总经理助理工作职责
2014/02/06 职场文书
基本公共卫生服务健康教育工作方案
2014/05/22 职场文书
铣工实训报告
2014/11/05 职场文书
紫日观后感
2015/06/05 职场文书
职场中的你,辞职信写对了吗?
2019/06/26 职场文书
五年级作文之成长
2019/09/16 职场文书
python自动统计zabbix系统监控覆盖率的示例代码
2021/04/03 Python
Python实战之实现简易的学生选课系统
2021/05/25 Python