分享

Cython 系列,完结撒花(不是完结的完结)

 古明地觉O_o 2022-12-08 发布于北京

不知不觉几个月又过去了,关于 Cython 系列暂时就先告一段落,不知道我的文章有没有让你有所收获呢,要是有的话就太好了。

下面回顾一下我们都学习了哪些内容:

1)了解了 Cython 是什么?以及它存在的意义,为什么 Cython 会出现。

2)通过对比 Cython, C, C 扩展以及纯 Python 之间的性能差异,了解了 Cython 如何对 Python 进行加速,以及应该在何时使用 Cython。

3)了解了编译 Cython 代码的几种方式,因为 Cython 代码是要经过编译的,编译方式可以是手动编译、也可以是自动编译。

4)通过对比静态语言和动态语言、以及编译执行和解释执行之间的差异,进一步理解了 Cython 的定位以及作用。

5)然后就是 Cython 的基础语法,包括变量的静态声明、静态函数、静态类、类型转换、异常处理、魔法方法等等。

6)Cython 同时理解 C 和 Python,在 Cython 里面可以直接声明 C 一级的结构,比如数组、指针、结构体、共同体、枚举等等。此外一些 C 级结构和 Python 结构是可以相互转换的,但是要注意内存管理相关的问题。

7)如果代码量很大、功能很复杂的话,就需要多文件编程了,所以我们还学习了 Cython 的工程化,如何将多个文件组织起来。核心就在于定义一个和 .pyx 文件具有相同基名称的 .pxd 文件,将那些想要提供给别的文件使用的 C 级结构都写在里面,然后通过 cimport 导入。

8)然后是 Cython 最核心的特性,就是包装外部的 C 代码。假设你有现成的 C 源文件,那么 Cython 可以直接对其进行包装,外界调用 Python 函数,在 Python 函数内部调用 C 函数。这样调用者就不清楚,这个功能是我们自己实现的,还是已经存在的。

9)Cython 不光可以封装 C 源文件,还可以封装动态库和静态库,而 C 已经存在大半个世纪了,拥有非常多的库。并且库的话,也可以使用 Go, Rust 编写,然后封装给 Cython 使用。

10)Python 在科学计算领域大放异彩的原因就在于,它能和 C 进行非常好的交互,并且数据之间可以共享内存,而共享内存的实现得益于缓冲区协议。Python 底层有一个结构体叫 Py_buffer,它内部有一个 buf 字段指向了缓冲区,所有实现缓冲区协议的对象一律通过 Py_buffer 来操作缓冲区,这样就屏蔽了不同对象之间的类型差异。

数据拷贝的时候,可以只拷贝 Py_buffer 结构体,但是结构体内部的 buf 字段指向的缓冲区不拷贝,从而实现共享内存。而我们也学习了缓冲区协议的具体细节,以及不同对象之间是如何共享缓冲区的,并且还通过 Cython 和 Python/C API 手动实现了缓冲区协议。

11)Python 有一个内置类型 memoryview,它存在的目的是在 Python 级别表示 C 级的缓冲区。但 Cython 提供了一个 typed memoryview,它是专门为 C 风格的访问而设计的,并且功能更加强大。

12)Numpy 数组是使用最广泛的数组,不仅具有出色的性能,还提供了大量丰富的 API 供我们使用。而 typed memoryview 和 Numpy 数组之间也是可以共享内存的,而共享内存的方式我们提供了三种。

13)最后是并行计算,上面不管再怎么优化,都是基于单线程的。这样性能的提升幅度有限,而合理地利用硬件资源是最有效的办法。所以我们介绍了 GIL 到底是个什么东西?它为什么会存在,存在的意义是什么?如何通过 Cython 将 GIL 释放掉,真正实现并行?以及 Cython 释放 GIL 的原理是什么,我们应该在何时释放 GIL,释放 GIL 又有哪些注意事项?

14)虽然 Cython 可以释放 GIL,但对于 for 循环来说其实是不够方便的。所以我们又学习了 prange,它专门用于 for 循环的并行。只需要将 range 换成 prange,即可接入所有可用的 CPU 核心,非常方便,但这个特性并不是所有的 C 编译器都支持。

总的来说,Cython 还是非常值得我们去学习的,通过学习 Cython,你也能更加深刻地了解 Python。

然后再看一下文章标题,上面写着"不是完结的完结",这是什么意思呢?因为 Cython 不仅可以包装 C,还可以包装 C++,而我不懂 C++。所以这个系列暂时结束,我去学习一段时间 C++ 之后,再把内容补上去。

可能有人觉得我这么做有点奇怪,为了介绍 Cython 还专门去学习 C++,其实原因是有一个读者问过我几次关于 Cython 包装 C++ 的问题。后面我跟他说,我去学一段时间 C++,然后再来帮你解决,因此我要实现约定。

所以该系列虽然完结了,但又没有完结,敬请期待后续内容。

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多