第6篇:Cython的面向对象--Python类 vs Cython扩展类

在Python中,一切都是对象。 具体来说是什么意思? 在最基本的层面上,一个对象具有三样东西

  • 标识(id):对象的标识将其与其他对象区分开来,并由id内置函数提供
  • 属性值(value):对象的值就是与之关联的数据,可以通过点表示法进行访问。通常,Python将对象的数据放在名为__ dict __的内部实例字典中。
  • 类型(type):对象指定该类型的对象表现出的行为。 这些行为可以通过称为方法的特殊功能进行访问。 当在对象上调用方法时,类型负责创建和销毁其对象,对其进行初始化以及更新其值。Python允许我们使用class语句在Python代码中创建新类型。

Python类型系统

我们知道Python的面向对象编程中,允许用户自定义的数据类型,在实例化Python的类对象时,该实例的属性值会保存到其内部dict中,即__ dict __属性,具有原生Python语义的类,其对象实例化前由Python解析器执行并经历如下过程(有些Python读物将这个过程步骤2到步骤4叫动态分派(Dynamic Dispatch),这里仅给出总结性的描述)

(首次加载序列化mashling格式的字节码)→从字节码缓存文件中解析实例属性的类型动态检查确定实例属性类型(类属性的尺寸)为其在实例化分配堆内存空间

  • 内置类型(Builtin Type):像object,list,dict,file,int float的数据类型,我们称为Python的内置数据类型,他们是通过Python的底层C接口实现的,并且默认整合到Python的运行时环境。
  • 用户定义类型(User Defined Type):在Python中通过使用关键字class定义的用户自定义数据类型。需要强调的该类型是具备Python语义的类(也就是纯Python代码定义的类),因此需要更多的开销。
  • 扩展数据类型(Extend Type):通过Pytho底层C接口定义的数据类型,例如C的关键字定义的struct,C++的关键字定义的class/struct定义的类,Cython的cdef class关键字定义的类.

不同类型的组合关系:

  • 在原生的Python代码中,不同Builtin Type(或扩展类型)以任意数量且不同类型的组合出包罗万象的User Definded Type,
  • 在原生的Python代码中 任意不同的User Defined Type的组合可以组合出规模更大的User Defined Type,组合的规模越大内存开销和实例化的时间开销就越大,并且在所有情况组合中,纯Python定义/组合的User Defined Type是最慢的。
  • 由于Builtin Type和Extend Type在C/C++底层定义并且在编译时类型静态绑定,因此初始化时绕过Python解析器的动态分派过程,直接提供高效的C级别内存分配和内存访问,因此以C/C++级别中,以任意不同的Builtin-Type或Extend Type组合出规模更大的Extend Type,性能相比User Defined Type仍然高出许多。

要直接在C/C++中实现Python的扩展类型需要开发者熟悉Python C底层接口,因此并不适合没有C/C++经验的开发者,然而Cython已经高度集成几乎所有C/C++的主流特性。能够以类似Python的语法快速定义出C/C++级别的Python扩展类型。

Cython中的扩展类

下面是一个简单的水果类,每种水果都有名称,数量,价格,Fruit类在纯Python的解析级别上定义(默认在.py文件中),当然也可以由Cython编译为C扩展

class Fruit(object):
    '''Fruit Type'''
    def __init__(self,nm,qt,pc):
          self.name=nm
          self.qty=qt
          self.price=pc

    def amount(self):
          return  self.qty*self.price

纯Python代码定义中,我们Frui对象实例化的时间开销是265ns

Cython编译后的Fruit2对象(类定义是一样,类名称不一样),时间开销是217ns

当我们使用cython将Fruit类编译为C时,生成的类只是Python在C级别的用户自定义类型,而不是扩展类型。 当Cython将其编译为C时,它仍然可以使用所有操作的动态分派的通用Python对象来实现。 所生成的代码大量使用Python底层C应用接口,并且与使用纯Python代码定义此类时的Python解释器进行相同的调用。

  • 由于消除了解释器解读字节码的开销,因此Cython版本的Fruit类仅具有很小的性能提升。
  • 它不能从任何静态类型中受益,因为Fruit类的C实现仍然必须依靠动态分派来在运行时解析类型

    ss8.png

要将上面的Python类转化为C级别的扩展类,只需对Fruit类做以下代码修改

  • 使用cdef关键字修饰class关键字,就是告知Cython编译器,将类编译成C级别的扩展类型
  • 在类级别下,使用cdef关键字声明类属性,并且为类属性静态指定C数据类型,目地类实例化时是绕过Python解释其
%%cython -a

cdef class Fruit(object):
    '''Fruit Type'''
    
   #类属性静态
    cdef str name
    cdef double qty
    cdef double price
    
    def __init__(self,nm,qt,pc):
          self.name=nm
          self.qty=qt
          self.price=pc

    def amount(self):
          return  self.qty*self.price


通过对Cython版本的Fruit类的类属性声明语句进行类型静态化后,我们实例化该实例的时间开销非常棒,最好的成绩是85.5ns


Cython编译的扩展类型比纯Python定义的用户定义类型快3倍多,比Cython编译的用户定义类型快2倍


目前这个Cython版本的Fruit类设计还不是最优的版本,我们下篇继续探讨有关Cython面向对象编程中的更多内容。

更新中....

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

推荐阅读更多精彩内容