<cython>学习笔记第一章:概要

Cython第一章,概要


开一个新坑,写点关于《Cython》的读书笔记
这本书暂时还没有中译吧,我看起来还是有点吃力,
全书的示例代码在:https://github.com/cythonbook/examples,最好配合起来看。

cython的目的是要将python和c/c++结合起来,
python是一种高层级的,动态的,解释性的,易学的语言,但是其带来的副作用是,运行效率可能会比静态编译语言慢几个数量级。我们可以使用python调用外部接口的方式,极大的提高python的运行效率。

对比Python,C和Cython

cython、c语言扩展python、纯python、纯c代码他们之间的运行效率究竟有多少差异,我们通过实例来对比一下。
位置:/examples/01-essentials/03-timings

我们先来看setup.py

from distutils.core import setup, Extension
from Cython.Build import cythonize

exts = ([Extension("cfib", sources=["cfib.c", "cfib_wrap.c"])] +
        cythonize("cyfib.pyx") +
        cythonize([Extension("wrap_fib", sources=["cfib.c", "wrap_fib.pyx"])])
        )

setup(
    ext_modules = exts,
)

setup.py中编译了三个动态库,

  1. cfib.c + cfib_wrap.c->cfib.so (使用纯c代码编写的python扩展)
  2. cyfib.pyx ->cyfib.so(使用cython语法生成python扩展)
  3. cfib.c + wrap_fib.pyx-> wrap_fib.so(使用cython包装了cfib.c生成python扩展)(这个库没有用来进行性能比较)

再分析Makefile

.PHONY : all
all:
    python setup.py build_ext -if
    gcc -O3 cfib.c main.c -o cfib.x

.PHONY : clean
clean:
    -rm -r build *.so *.pyc cyfib.c *.x wrap_fib.c

make的时候调用setup.py,同时也编译了cfib.c和main.c为一个可执行文件cfib.x。继续看cfib.c:

#include "cfib.h"
//计算斐波那契数列的第n个值
double cfib(int n) {
    int i;
    double a=0.0, b=1.0, tmp;
    for (i=0; i<n; ++i) {
        tmp = a; a = a + b; b = tmp;
    }
    return a;
}

看main.c:

#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include "cfib.h"

int main(int argc, char **argv) {
    int arg=-1, numiter=-1, i;
    clock_t t;

    if (argc != 3) {
        printf("Wrong number of arguments, expecting 2 (got %d)\n.", argc-1);
        return 1;
    }

    arg = atoi(argv[1]);
    numiter = atoi(argv[2]);

    t = clock();
    for (i=0; i<numiter; ++i) {
        cfib(arg);
    }
    t = clock() - t;
    printf("%f\n", ((float)t) / CLOCKS_PER_SEC / numiter * 1e9);

    return 0;
}

可以看出main.c接受两个参数,调用cfib(arg)循环numiter次,然后的到总时间并计算出每次计算斐波那契数的平均时间,用纳秒来表示(10的-9次方秒),现在我们确定了cfib.x程序的作用。

需要对比以下四个库的效率,每个库都将计算fib(90)的值循环10万次,统计出每次fib计算的平均时间(纳秒)

  1. fib.py (纯python计算斐波那契数)
  2. cfib.c + cfib_wrap.c->cfib.so (使用纯c代码编写的python扩展)
  3. cyfib.pyx ->cyfib.so(使用cython语法生成python扩展)
  4. cfib.c + main.c ->cfib.x (纯c)

执行

make
python timings.py

在我的机器上计算的结果为:

纳秒
1.纯python:408
2.纯C扩展python模块cfib.so:139
3.Cython扩展python模块cyfib.so:62
4.纯C语言cfib.x:4

可以看出,对于计算斐波那契数这样的消耗cpu的运算来说,python比纯C语言程序慢两个数量级,手工使用python的C语言API进行扩展不如使用cython(因为cython对其进行了优化),cython对python的扩展可以提高1个数量级的效率

使用cython包装c代码(好像前面一个小结也设计到这个内容了)

查看对应位置的5个源文件,其中setup和Makefile都不是必须的,必要的时候可以自己编译,我们的目标是将wrap_fib.pyx 编译成wrap_fib.so,python可以直接import wrap_fib

位置:/examples/01-essentials/02-wrapping-c-code-with-cython/

源代码
cfib.h  cfib.c  wrap_fib.pyx setup.py Makefile 
-----------------
cfib.h
#ifndef __CFIB_H__
#define __CFIB_H__
double cfib(int n);
#endif
-----------------
cfib.c
#include "cfib.h"
double cfib(int n) {
    int i;
    double a=0.0, b=1.0, tmp;
    for (i=0; i<n; ++i) {
        tmp = a; a = a + b; b = tmp;
    }
    return a;
}
------------------
wrap_fib.pyx
cdef extern from "cfib.h":
    double cfib(int n)

def fib(n):
    ''' Returns the nth Fibonacci number.'''
    return cfib(n)
-------------------
setup.py
from distutils.core import setup, Extension
from Cython.Build import cythonize
#Extention:wrap_fib(c扩展的名字),source:一个源码文件的列表
exts = cythonize([Extension("wrap_fib", sources=["cfib.c", "wrap_fib.pyx"])])

setup(
    ext_modules = exts,
)
-------------------
Makefile
.PHONY : all
all:
        python setup.py build_ext -if

.PHONY : clean
clean:
        -rm -r build *.so wrap_fib.c

在cython中,我们将.pyx转化为.c,再编译成.so共享库,使用了python自带的distutils进行.c->.so的编译,有了以上这5个文件,再执行make,会发现文件夹里多了build/,wrap_fib.c,wrap_fib.so,其中wrap_fib.so为我们的目标库,可以直接被python引用。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 151,829评论 1 331
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 64,603评论 1 273
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 101,846评论 0 226
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 42,600评论 0 191
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 50,780评论 3 272
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 39,695评论 1 192
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,136评论 2 293
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 29,862评论 0 182
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,453评论 0 229
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 29,942评论 2 233
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,347评论 1 242
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 27,790评论 2 236
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,293评论 3 221
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,839评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,448评论 0 181
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 34,564评论 2 249
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 34,623评论 2 249

推荐阅读更多精彩内容