欢迎来到Cython教程。 Cython的目的是充当Python和C / C ++之间的中介。 从本质上讲,Cython是Python语言的超集,它允许为变量和类属性添加数据类型,然后可以将其转换为C代码和Python的C扩展。
与非Python程序员朋友和同事交流,很可能您已经被问及为什么使Python,正确来说是CPython是一种“慢”语言!确实慢~!,最大的诟病就是GIL限制,因此python是一个“伪并行”的语言。所以为了纠正GIL这个诟病后来才有各种python的分支,Jython,Ipython,pypy等,并形成各自的软件生态。现在python这个名词从概念上已经不是某种动态语言的专属名词,它更像各种静态语言实现它的一种动态语言规范.
而这里Cython作为CPython的一种祢补方案,我们熟知Numpy,Pandas和Scikit这样的库都是C优化的。 当你使用它们时,你实际上是在利用C / C ++的强大功能,而Python只是作为一种胶水语言提供了这些库的应用接口支持。 更进一步说,Numpy,Pandas和Scikit-learn都使用了Cython! 很有可能,这些流行的库中使用Python + C优化的代码,如果你的C和python功底扎实的话,使用Cython将比你自己编写的C代码快得多。OK,学习cpython的最终归属其实就是C/C++,也可以说是Cython!
n=7.0
在python的角度里可以随意对变量n赋予任何它支持的数据类型。因为Python每次都会检查你的类型,这种“动态类型”检测必定造成时间消耗,这也是python会被认为慢的其中一个因素。
我们可以使用静态类型和Cython来获得速度上的提升。 许多静态语言更像是:
float n = 5.0
而Cython 就会是这样
cdef float x = 5.0
当然你需要将x保持为float,但是,只要使用静态类型,你就会得到很大的回报。 要做到这一点,我们需要两件事.
- cython :很简单通过pip install cython安装即可
- c/c++编译器:
- Linux系统并且作为开发用途的话,基本gcc c/c++编译工具都有的 ,不清楚的话请自行搜索其他相关文章。
- Windows用户请查看关于MinGw环境搭建的Cython官方教程https://cython.readthedocs.io/en/latest/src/tutorial/appendix.html
由于我写本文用到的是mac所以重点,以mac搭建的环境为主.一旦你有Cython和编译器,让我们通过Cython工作流程并制作我们自己的C-Exension! 让我们从一个简单的python文件开始:
先创建一个后缀名为.pyx的cython源文件
def say_hello(name):
return f'Hello,{name}^_^'
#end-def
接下来创建一个setup.py文件
from distutils.core import setup
from Cython.Build import cythonize
setup(ext_modules = cythonize('example_cython.pyx'))
接下来,在您的终端中,执行以下命令:
python setup.py build_ext --inplace
现在应该创建一个build目录,一个C文件(hello.c)和有一些反馈信息
Cython directive 'language_level' not set, using 2 for now (Py2). This will change in a later release! File: /Volumes/Seagate/cytest/hello.pyx
tree = Parsing.p_module(s, pxd, full_module_name)
running build_ext
building 'hello' extension
creating build
creating build/temp.macosx-10.9-x86_64-3.7
jkmac:cytest apple$
和下面两条gcc链接和编译的指令,copy后分别手动执行一次
gcc -Wno-unused-result -Wsign-compare -Wunreachable-code \
-fno-common -dynamic -DNDEBUG -g -fwrapv -O3 -Wall \
-arch x86_64 -g \
-I/Library/Frameworks/Python.framework/Versions/3.7/include/
python3.7m
-c hello.c -o build/temp.macosx-10.9-x86_64-3.7/hello.o
gcc -bundle -undefined dynamic_lookup -arch x86_64 \
-g build/temp.macosx-10.9-x86_64-3.7/hello.o
-o /Volumes/Seagate/cytest/hello.cpython-37m-darwin.so
之后会生成一个共享对象文件(.so).在这个示例中应该是hello..so的类似名称,我们就导入我们的C扩展。
最后,为了测试我们的扩展是否成功,新建一个python文件,这里是app.py
from hello import say_hello
print(say_hello('jck308'))
我们运行一次 传递我的昵称'jck308'可以正常输出.
OK,开了个头,其他后续,敬请期待...