Cython目标
Cython主要是针对python性能太差,解决尤其是cpu矩阵运算,循环运算的性能问题而诞生。
Cython将你的类python代码编译成c链接库,你可以自己定义哪些运算可以交给c代码去运行。如果你想使用Cython,代表你已经开始关注计算性能了,榨取性能不只是交给C来处理就应该满足的,你可能还需要关注python语句里可优化的代码。
安装
1 | $ pip3 install Cython |
配置Pycharm
Preferences -> Tools -> External Tools新添加一个用户配置
1 | # $xxx$均是宏插入,本设置用于将.pyx代码编译为c时所用 |
.pxd/.pyd/.pyx区别
- .pxd
.pxd是扩展模块头文件,类似于C语言的.h头文件,.pxd文件中有 Cython模块要包含的Cython声明。.pxd文件还可为.pyx文件模块提供 Cython接口,以便其它Cython模块可使用比Python更高效的协议与之进行通信。
可用cimport关键字将.pxd文件导入.pyx模块文件中。
- .pyx
.pyx是扩展模块源代码文件,类似于C语言的.c源代码文件,.pyx文件中有 Cython模块的源代码。
.pyx必须先被编译成.c文件,再编译成.pyd(Windows)或.so(Linux)文件,才可作为模块import导入使用。
- .pyd
.pyd是由其它编程语言”编写-编译”生成的Python扩展模块。Python要导入.pyd文件,把它当成module来用就可以了,”import ${path}.modulename”。
示例一. 使用c代码
1 | +-- cfib.c |
1 | //cfib.h |
1 | //cfib.c |
1 | //fib.pyx |
1 | //setup.py |
右键setup.py,External Tools -> accountname编译
性能测试:
1 | def fib_python(n): |
示例二. 径向基函数的近似计算
- 公式:
1 | //fastloop.pyx |
1 | //setup.py |
性能测试:
1 | from math import exp |
1 | ##结果: |
cython怎样找到性能优化点
1 | $ cython xxxxx.pyx -a |
生成的html黄色部分则是可以做性能优化的点。
如上例二fastloop.pyx,使用
1 | from libc.math cimport exp |
代替
1 | from math import exp |
其他
timeit
1 | timeit.timeit(stmt='pass', setup='pass', timer=<default timer>, number=1000000, globals=None) |
python调用c
使用ctypes
1 | from ctypes import cdll,c_char_p,c_int,c_double |
python代码优化
- 减少变量公有,能的就用变为私有
- 尽量使用函数,减少全局声明和定义
- 尽可能去掉属性访问,减少.的使用次数,尤其是循环中
- 更多使用局部变量,尽量少的全局变量
- 避免不必要的抽象,可以直接访问,不要用get/set方法
- 使用内置的数据类型,自己封装的类更慢
- 避免创建不必要的数据结构或复制