文件总览
.
+-- main.py
+-- fib
| +-- __init__.py
| +-- cfib.c
| +-- cfib.h
| +-- fib.pyx
| +-- setup.py
说明:
main.py 主程序__init__.py 是模块引用文件cfib.c 用c写的fib函数cfib.h 是cfib的头文件,供fib.pyx 参照fib.pyx 是Cython文件setup.py 是用来编译Cython的
代码
cfib.c :
#include "cfib.h"
unsigned long fib(unsigned long n) {
unsigned long a=0, b=1, i, tmp;
for (i=0;i<n;++i) {
tmp = a; a = a + b; b = tmp;
}
return a;
}
cfib.h :
#ifndef __CFIB_H__
#define __CFIB_H__
unsigned long fib(unsigned long n);
#endif
cfib.c 和cfib.h 就是标准的c程序写法,就不赘述,主要拿来比performance的
fix.pyx :定义引用的c函数
cdef extern from "cfib.h":
unsigned long _fib "fib"(unsigned long n)
def fib_c(n):
'''Returns the nth Fibonacci number.'''
return _fib(n)
def fib_cython(n):
'''Returns the nth Fibonacci number.'''
a, b = 0, 1
for i in range(n):
a, b = a + b, a
return a
def fib_cython_optimized(unsigned long n):
'''Returns the nth Fibonacci number.'''
cdef unsigned long a=0, b=1, i
for i in range(n):
a, b = a + b, a
return a
__init__.py :
from .fib import *
setup.py :
from distutils.core import setup, Extension
from Cython.Build import cythonize
setup(ext_modules = cythonize(Extension(name="fib", sources=["cfib.c", "fib.pyx"])))
Pycharm
打开PyCharm,到settings => Tools => External Tools ,然後点+,新增一个工具,设置如下:
Porgram :$ModuleSdkPath$ 即python可执行文件路径 Arguments :$FilePath$ build_ext --inplace Working directory :$FileDir$
这样基本上就大功告成了,然后回到Project对setup.py点右键,选External Tools ,选CythonBuild 就可以看到开始跑了 如果设置对的话,就可以看到编译成功的信息 当然为了避免每次编译pyx文件的时候都点击的话,可以直接设置该tool的快捷键。
最后就可以来跑跑看啦,main.py 如下:
def fib_python(n):
'''Returns the nth Fibonacci number.'''
a, b = 0, 1
for i in range(n):
a, b = a + b, a
return a
if __name__ == '__main__':
print("##### check result #####")
import fib
print("fib(47) in python:", fib_python(47))
print("fib.fib_c(47):", fib.fib_c(47))
print("fib.fib_cython(47):", fib.fib_cython(47))
print("fib.fib_cython_optimized(47):", fib.fib_cython_optimized(47))
print("\n##### performace benchmark #####")
import timeit
python_setup = "from __main__ import fib_python"
cython_setup = "import fib"
print("Python code: ", timeit.timeit('fib_python(47)', setup=python_setup), "seconds")
print("Cython code: ", timeit.timeit('fib.fib_cython(47)', setup=cython_setup), "seconds")
print("Optimized Cython code: ", timeit.timeit('fib.fib_cython_optimized(47)', setup=cython_setup), "seconds")
print("C code: ", timeit.timeit('fib.fib_c(47)', setup=cython_setup), "seconds")
输出结果:
C:\Users\*****\Miniconda3\envs\idp\python.exe D:/Dropbox/Data/programming/Python/Cython/1_fib/main.py
fib(47) in python: 2971215073
fib.fib_c(47): 2971215073
fib.fib_cython(47): 2971215073
fib.fib_cython_optimized(47): 2971215073
Python code: 2.9352622053858113 seconds
Cython code: 1.7331176511158422 seconds
Optimized Cython code: 0.14643933094340067 seconds
C code: 0.11884286952119272 seconds
Process finished with exit code 0
参考
Pycharm and Cython
|