Cython学习笔记1:利用Cython加速Python运行速度

news2025/2/22 2:40:07

Cython学习笔记1:利用Cython加速Python运行速度

  • Cython
    • Cython 的核心特点:
    • 利用Cython加速Python运行速度
      • 1. Cython加速Python运行速度原理
      • 2. 不使用Cython
      • 3. 使用Cython加速
        • (1)使用pip安装 cython 和 setuptools 库
        • (2)安装c语言编译器
        • (3)创建要编译为动态链接库的.py文件
        • (4)创建setup.py
        • (5)把.py转化为库文件
        • (6)python程序调用库
        • (7)annotate参数
        • (8)定义变量的类型加速python运行速度

Cython

Cython 是一个用于将 Python 代码转换为 C 语言扩展模块的编程语言。它允许你在 Python 中编写 C 风格的代码,从而提高性能,尤其是在需要大量计算的情况下。通过将 Python 代码与 C 代码混合使用,Cython 既保留了 Python 的简洁性,又能提升程序的执行速度。

Cython 的核心特点:

  1. 提高性能:Cython 可以将 Python 代码编译成 C 语言代码,然后生成高效的 C 扩展模块。它适用于需要频繁计算的任务,尤其是数值计算和循环处理。
  2. 与 C 代码交互:Cython 允许直接调用 C 函数和访问 C 数据结构,从而减少了 Python 和 C 之间的接口调用开销。
  3. 简化 C 接口:与直接使用 C 语言不同,Cython 通过 Python 风格的语法简化了 C 接口的使用,开发者可以快速将 Python 代码提升到 C 代码的性能。
  4. 无缝集成:Cython 代码可以与现有的 Python 代码无缝集成,开发者不需要重写整个程序,通常只需要优化性能瓶颈部分。

利用Cython加速Python运行速度

以计算圆周率 π 为例子,使用Nilakantha 级数来计算 π 值,计算公式如下:
在这里插入图片描述

1. Cython加速Python运行速度原理

在这里插入图片描述
把 python 代码转化为 c 语言代码,然后再编译成动态链接库,最后使用 python 程序调用这个库

2. 不使用Cython

创建 2 个 .py文件,fun.pyNilakantha_main.py

fun.py 用于写计算的函数
Nilakantha_main.py 用于调用函数,查看结果和运行时间
在这里插入图片描述
fun.py代码如下

def calculate_pi(count: int) -> float:
    pi = 3.0
    sign = 1
    for i in range(2, count * 2, 2):
        term = sign * 4.0 / (i * (i + 1) * (i + 2))
        pi += term
        sign *= -1
    return pi

Nilakantha_main.py代码如下

import time
import fun


def main():
    start_time = time.time()
    print(fun.calculate_pi(20_000_000))
    end_time = time.time()
    print('Time:', end_time - start_time)


if __name__ == '__main__':
    main()

运行Nilakantha_main.py文件后,结果如下:

3.141592653589787
Time: 4.7696967124938965

这段代码设置了迭代次数为2千万次,最后耗时4.76秒
下面使用cython加速

3. 使用Cython加速

(1)使用pip安装 cython 和 setuptools 库

使用如下命令进行安装,使用清华镜像源,这样速度更快

pip install cython setuptools -i https://pypi.tuna.tsinghua.edu.cn/simple

安装好后再安装就会出现下面的结果

在这里插入图片描述

(2)安装c语言编译器

下面的c语言编译器安装一款就可以了,博主是Windows11系统,安装的是Visiual Studio 2022

  1. GCC (GNU Compiler Collection)
  2. Clang
  3. Microsoft Visual C++ (MSVC)
  4. MinGW (Minimalist GNU for Windows)
(3)创建要编译为动态链接库的.py文件

新建一个名为fun_compile.py的文件,用于将它最后编译为动态链接库,让 python 程序调用
fun_compile.py代码如下

# cython: language_level=3
def calculate_pi(count: int) -> float:
    pi = 3.0
    sign = 1
    for i in range(2, count * 2, 2):
        term = sign * 4.0 / (i * (i + 1) * (i + 2))
        pi += term
        sign *= -1
    return pi

# cython: language_level=3

这一行代码的作用是:指示 Cython 编译器使用 Python 3 语法的指令,告诉 Cython 如何解析和编译 Python 代码,确保代码遵循 Python 3 的语法规则,而不是 Python 2

(4)创建setup.py

setup.py 是 Python 项目中用于打包和分发代码的脚本,它包含了项目的元数据和配置,用于指导 Python 工具(setuptools)如何构建、安装和分发项目。

setup.py中的代码如下

from Cython.Build import cythonize
from setuptools import setup

setup(
    ext_modules=cythonize(["fun_compile.py"]),
)

fun_compile.py是编译为动态链接库的 python 代码

(5)把.py转化为库文件

当前目录下的文件如下展示

在这里插入图片描述
在此目录下,执行命令

python setup.py build_ext --inplace

过程展示如下

在这里插入图片描述
运行完成后,目录里会多出一个 .c 文件和一个库文件
在这里插入图片描述

(6)python程序调用库

修改Nilakantha_main.py,导入fun_compile如果既存在fun_compile.py,也存在fun_compile.py产生的库,会优先调用动态链接库。代码如下:

import time
import fun
import fun_compile


def main():
    start_time = time.time()
    print(fun.calculate_pi(20_000_000))
    end_time = time.time()
    print('Time:', end_time - start_time)

    start_time = time.time()
    print(fun_compile.calculate_pi(20_000_000))
    end_time = time.time()
    print('Time:', end_time - start_time)


if __name__ == '__main__':
    main()

运行结果如下:
在这里插入图片描述
可以看到确实加速了

(7)annotate参数

修改setup.py,加入一个参数annotate=True

from Cython.Build import cythonize
from setuptools import setup

setup(
    ext_modules=cythonize(["fun_compile.py"], annotate=True),
)

然后执行命令

python setup.py build_ext --inplace

结果会多出来一个.html文件
在这里插入图片描述
annotate=True 参数的作用是:生成 Cython 编译时的注释文件,用于查看 Cython 将 Python 代码转换为 C 代码的详细过程和每一步的性能分析。

通过浏览器打开这个.html文件

在这里插入图片描述
黄色线条的代码表示翻译后的代码依赖 python 代码,颜色越深,依赖越强
点击“+”开头的行,可查看 Cython 为其生成的 c语言 代码

点开红色框的这一行,可以看到这行代码都是用 python实现的
在这里插入图片描述
如果想让这段代码不都用 python 来实现,可以给其中的变量添加类型,这就是这段代码没有用c语言实现的原因,因为cython不知道变量的类型。

(8)定义变量的类型加速python运行速度

修改fun_compile.py文件,代码如下:

# cython: language_level=3
import cython


def calculate_pi(count: int) -> float:
    pi = 3.0
    sign = 1
    for i in range(2, count * 2, 2):
        term = sign * 4.0 / (i * (i + 1) * (i + 2))
        pi += term
        sign *= -1
    return pi


def calculate_pi_annotated(count: int) -> float:
    pi: cython.double = 3.0
    sign: cython.int = 1
    i: cython.int
    for i in range(2, count * 2, 2):
        term: cython.double = sign * 4.0 / (i * (i + 1) * (i + 2))
        pi += term
        sign *= -1
    return pi

重新编译

python setup.py build_ext --inplace

修改Nilakantha_main.py,代码如下:

import time
import fun
import fun_compile


def main():
    start_time = time.time()
    print(fun.calculate_pi(20_000_000))
    end_time = time.time()
    print('Time:', end_time - start_time)

    start_time = time.time()
    print(fun_compile.calculate_pi(20_000_000))
    end_time = time.time()
    print('Time:', end_time - start_time)
    
    start_time = time.time()
    print(fun_compile.calculate_pi_annotated(20_000_000))
    end_time = time.time()
    print('Time:', end_time - start_time)


if __name__ == '__main__':
    main()

运行后结果如下
在这里插入图片描述
可以看到加入变量类型加入后的代码运行效果更快了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2302207.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

web的分离不分离:前后端分离与不分离全面分析

让我们一起走向未来 🎓作者简介:全栈领域优质创作者 🌐个人主页:百锦再新空间代码工作室 📞工作室:新空间代码工作室(提供各种软件服务) 💌个人邮箱:[1504566…

记录一个ES分词器不生效的解决过程

问题背景 商城项目,其中商品查询检索使用的是ES, 但存在某些商品查询不到的问题 例如:某商品名包含AA_BBB这样的关键词,但是搜索"AA"不能查询到该商品,但是将商品名修改为AA BBB后就能查询到了. 怀疑是分词的问题,但看代码,在创建ES索引时在对应字段上也定义了分词器…

高性能内存对象缓存Memcached详细实验操作

目录 前提准备: cache1,2: 客户端cache-api(一定得是LAMP环境) memcache实现主主复制以及高可用(基于以上完成) cache1,2: memcachekeepalived(基于以上完成) cache1,2: 前提准备: 1. 准备三台cent…

css之display:grid布局改块级元素布局

1.问题: div是块级元素,一个div元素占一行,但是,今天测试样式时,总是会有两个div并占一行,很困惑,结果发现是app这个样式 在main.css里 #app样式布局在main.ts里被应用 2.原因以及样式分析 im…

推荐一个github star45k+进阶的java项目及知识的网站

mall是github上star 45k的一个java项目 mall项目是一套电商系统,包括前台商城系统及后台管理系统,基于SpringBootMyBatis实现,采用Docker容器化部署。 前台商城系统包含首页门户、商品推荐、商品搜索、商品展示、购物车、订单流程、会员中心…

第2章 深入理解Thread构造函数

Thread的构造函数。 2.1 线程的命名 在构造一个Thread时可以为其命名。 2.1.1 线程的默认命名 下面构造函数中,并没有为线程命名。 Thread() Thread(Runnable target) Thread(ThreadGroup group, Runnable target)打开源码会看到 public Thread(Runnable targe…

node 使用 Redis 缓存

缓存是什么? 高并发下,一个项目最先出问题的,并不是程序本身,而是数据库最先承受不住。 在数据库上我们可以做很多优化,例如优化 SQL 语句,优化索引,如果数据量大了,还可以分库、分表…

PMBOK第7版整体架构全面详解

1. 引言 7月1日对于项目管理从业者和研究者而言,是个非凡意义的一个时间,这一天,翘首以待的《 项 目管理知识体系指南 》(PMBOK)第七版终于发布了。 总体而言,PMBOK第七版集百家之所长,成一…

【Scrapy】Scrapy教程6——提取数据

前一小节我们拿到了页面的数据,那页面中那么多内容,我们想要其中的部分内容,该如何获取呢?这就需要对我们下载到的数据进行解析,提取出来想要的数据,这节就讲讲如何提取数据。 引入 我们编辑保存下来的shouye.html文件看下,发现这是什么鬼,全是如下图的代码。 没错…

golang panic信息捕获

背景 我们的日志接入阿里云sls平台,但是,日志是以json的格式存储在阿里云sls平台上,程序中产生的error,info等日志都可以实现以json的格式打印。但是,golang程序中产生的panic信息本身不是以json的格式输出,这就导致p…

一周学会Flask3 Python Web开发-http响应状态码

锋哥原创的Flask3 Python Web开发 Flask3视频教程: 2025版 Flask3 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili 在Flask程序中,客户端发出的请求触发相应的视图函数,获取返回值会作为响应的主体,最后生成…

goland无法debug项目

1、其实个原因是因为正在使用的Delve调试器版本太旧,无法兼容当前的Go语言版本1.2。Delve是Go语言的一个调试工具,用于提供源码级别的调试功能。Go语言每隔一段时间会发布新版本,而相应的调试器Delve也可能会更新以提供新的特性或修复已知问题…

Python VsCode DeepSeek接入

Python VsCode DeepSeek接入 创建API key 首先进入DeepSeek官网,https://www.deepseek.com/ 点击左侧“API Keys”,创建API key,输出名称为“AI” 点击“创建",将API key保存,复制在其它地方。 在VsCode中下载…

Ubuntu22.04.6如何固定ip地址

Ubuntu22.04.6如何固定ip地址 主要参见这篇博客 ubuntu 桌面版如何设置固定IP地址_ubuntu桌面版如何修改ip-CSDN博客 1.先查看一下当前的IP是多少

腿足机器人之十- SLAM地图如何用于运动控制

腿足机器人之十- SLAM地图如何用于运动控制 腿足机器人SLAM地图的表示与处理全局路径规划:地形感知的路径搜索基于A*的三维路径规划基于RRT*的可行步态序列生成 局部运动规划:实时步态调整与避障动态窗口法的腿足适配模型预测控制(MPC&#x…

毕业项目推荐:基于yolov8/yolov5/yolo11的果蔬检测识别系统(python+卷积神经网络)

文章目录 概要一、整体资源介绍技术要点功能展示:功能1 支持单张图片识别功能2 支持遍历文件夹识别功能3 支持识别视频文件功能4 支持摄像头识别功能5 支持结果文件导出(xls格式)功能6 支持切换检测到的目标查看 二、数据集三、算法介绍1. YO…

pyside6学习专栏(二):程序图像资源的加载方式

pyside6中的QLabel控件可以加载图像和gif动画,可以直接从外部文件加载,也可以从QRC类型的文件(实际是一脚本文件)经编绎生成对应的资源.PY模块文件(就是将qrc文本中指定的资源文件的16制内容写入.py文件)来使用,本文对两种方式作了一简单的示…

如何在 VS Code 中快速使用 Copilot 来辅助开发

在日常开发中,编写代码往往是最耗时的环节之一。而 GitHub Copilot,作为一款 AI 编码助手,可以帮助开发者 自动补全代码、生成代码片段,甚至直接编写完整的函数,大幅提升编码效率。那么,如何在 VS Code 中快…

DeepSeek-R1论文阅读及本地调用

前言 DeepSeek已经火了一段时间了,对于这项“国运级”的技术成果,即便研究的不是这个方向,也不免好奇前来看看。本文将先解析一下DeepSeek-R1这篇论文,再对DeepSeek的本地部署使用进行研究配置。 论文标题:DeepSeek-…

自然语言处理:第九十二章 chatBI 经验(转载)

本人项目地址大全:Victor94-king/NLP__ManVictor: CSDN of ManVictor 原文连接: 一文分享 ChatBI 实践经验 写在前面: 笔者更新不易,希望走过路过点个关注和赞,笔芯!!! 写在前面: 笔者更新不易,希望走过路过点个关注和赞&#x…