面向对象的纯粹性
在很久很久以前,C++还被称为面向对象语言(现在一般称为多范式通用语言),人们就对C++的面向对象的纯粹性提出了质疑,主要有以下几点:
- 并非所有的对象都是对象(很拗口?),比如指针本身不是对象,函数不是对象,基本数据类型不是对象。
- C++对于面向对象中“消息传递”的设计采用的是方法调用的形式,这种方式不能完整的表达“消息传递”的语义。
对于第一点,我们最直观的感受就是,我们无法写如下的代码:
2 |
string b = a.toString(); |
我们能做的只是:
2 |
char buffer[MAX_STRING]; |
3 |
itoa(a, buffer, MAX_STRING]; |
所以这里a是一个值,而非一个对象,它只是数据,而没有与之相关的操作。
我们看看Lua和Python的设计,就可以更加明了的理解值类型的设计的差异个中差异。
Lua和Python的差异
在Python中,所有的对象都继承自PyObject类(Python本身是使用C语言编写的,Python在C语言中模拟了一套类似C++的OO机制,支持继承、多态等面向对象特性),在所有需要操作变量的地方,都统一使用PyObject*来访问,例如,在函数调用时,为函数分配堆栈空间的时候,代码就类似这个样子:
1 |
PyObject** stack = (PyObject**)malloc(sizeof(PyObject*)*maxStack); |
所以,本质上来说,所有的对象都是在堆上分配的,我们访问的都是对象的指针。
再来看看Lua的设计,在Lua中,使用一个结构体来保存对象:
所以,保存一个变量,在32bit的机器上,Lua使用12个字节。对于值类型(lua_Number)之类的变量,并不会从堆中分配,而是直接在栈上分配(事实上也是从堆上分配,但是是一次性分配的),例如在函数调用的时候,要分配寄存器的空间的时候,相当于这样的代码:
1 |
TObject* locals = (TObject*)malloc(sizeof(TObject)*localCount); |
这样看起来似乎都是一条malloc调用,那么性能差异在哪里呢?
分配空间时的性能差异
假设我们在两个虚拟机里面都需要分配一个4个数值类型的栈上变量或者寄存器的空间,那么在Python中,等效代码是:
1 |
PyObject** stack = (PyObject**)malloc(sizeof(PyObject*)*4); |
2 |
for (int i = 0; i < 4; i++) |
3 |
stack[i] = (PyObject*)malloc(sizeof(PyIntObject)); |
这里的代码只包含分配空间,不包括初始化变量的部分。对应在lua虚拟机中的相对代码就是:
1 |
TObject* locals = (TObject*)malloc(sizeof(TObject)*4); |
可以看到,Lua的模式在处理数值变量的时候,将会少4次内存分配操作,这对于每秒执行数以万级的函数调用的时候,对性能的影响非常明显。
执行运算时的性能差异
现在我们再看看执行数值运算的时候性能会有怎样的差异,我们还是以上一篇文章中说到的,1+2的数学运算为例,将相应的bytecode翻译成实际执行的C代码来做:
Python ByteCode
对应的C代码
02 |
PyObject** stack = (PyObject**)malloc(sizeof(PyObject*)*2); // 一次内存分配 |
06 |
STACK_TOP = PyInt_FromLong(1); // 一次内存分配 |
10 |
STACK_TOP = PyInt_FromLong(2); // 一次内存分配 |
13 |
PyObject* result = PyNumber_Add(STACK_SECOND, STACK_TOP); // 一次内存分类 |
我们可以看到,这样一次简单的计算,进行了4次内存分配操作(其实还有2次内存释放操作)。
我们再来看看Lua的ByteCode:
对应的C代码是:
01 |
TObject* locals = (TObject*)malloc(sizeof(TObject)*3); // 一次内存分配 |
04 |
locals[0] = lua_Number(1); // 没有内存分配 |
07 |
locals[1] = lua_Number(2); |
10 |
locals[2] = lua_Number(locals[0].v.n + locals[1].v.n); |
只有1次内存分配操作,没有内存释放操作,这样,速度的差异就非常明显了。
文章来源:http://zoomq.qiniudn.com/ZQScrapBook/ZqFLOSS/data/20111002195204/
- Python数据模型与Python对象模型
数据模型==对象模型 Python官方文档说法是"Python数据模型",大多数Python书籍作者说法是"Python对象模型",它们是一个意思,表示&quo ...
- Python虚拟机类机制之对象模型(一)
Python对象模型 在Python2.2之前,Python中存在着一个巨大的裂缝,就是Python的内置类type,比如:int和dict,这些内置类与程序员在Python中自定义的类并不是同一级别 ...
- 【Python源码剖析】对象模型概述
Python 是一门 面向对象 语言,实现了一个完整的面向对象体系,简洁而优雅. 与其他面向对象编程语言相比, Python 有自己独特的一面. 这让很多开发人员在学习 Python 时,多少有些无所 ...
- Python 描述符(descriptor) 杂记
转自:https://blog.tonyseek.com/post/notes-about-python-descriptor/ Python 引入的“描述符”(descriptor)语法特性真的很黄 ...
- 作为比湖南还火的python网红,零基础要如何系统的开始学习呢?
Python(发音:英[?pa?θ?n],美[?pa?θɑ:n]),是一种面向对象.直译式电脑编程语言,也是一种功能强大的通用型语言,已经具有近二十年的发展历史,成熟且稳定.它包含了一组完善而且容易理 ...
- Python知识梳理
这是个人学习笔记,非教程,内容会有些混乱 极简教程 数据类型 我们可以使用type()函数类获取对象的类型,Python3中内置数据类型包括:None,int,float,complex,st ...
- 如何学Python
如何学习Python? Python上手很容易, 基本有其他语言编程经验的人可以在1周内学会Python最基本的内容.它们包括:1.常用内置类型(int, float, bool, bytes, st ...
- Python 基本数据类型(2)
知识内容: 1.python对象模型 2.数字与bool 3.字符串 4.列表与元组 5.字典与集合 一.python对象模型 1.python对象模型 对象是python语言中最基本的概念,在pyt ...
- python's object model
[python's object model] 1.object.__init__(self[, ...]) 如果subclass没有实现__init__,那么python类在实例化的时 ...
随机推荐
- position定位-absolute与fixed
1. absolute 生成绝对定位元素,相对于static定位以外的第一个父元素进行定位. 2. fixed 生成绝对定位元素,相对于浏览器窗口进行定位.
- CentOS修改DNS、IP地址、网关
一.CentOS 修改DNS 修改对应网卡的DNS的配置文件 # vi /etc/resolv.conf 修改以下内容 nameserver 8.8.8.8 #google域名服务器 nameserv ...
- Flink的序列化与flink-hadoop-compatibility
最近 用户提交了一个问题 说他的jar包里明明包含相关的类型 但是在提交Flink作业的时候 却报出classnotfound的错误 查看之后发现 这里是flink的一个没有说的太明白的地方 用户的代 ...
- Codeforces 498B Name That Tune
不想说啥了…这是我被卡常数卡得最惨的一次… 首先根据期望的线性性,我们考虑每首歌能够被认出来的概率,也就是每首歌对答案贡献的期望.那么定义F[i]为第i首歌被认出来的概率是做不了的,自然想到F[i][ ...
- 详细图解jQuery对象,以及如何扩展jQuery插件
详细图解jQuery对象,以及如何扩展jQuery插件 早几年学习前端,大家都非常热衷于研究jQuery源码.我还记得当初从jQuery源码中学到一星半点应用技巧的时候常会有一种发自内心的惊叹,“原来 ...
- 【刷题】BZOJ 3140 [Hnoi2013]消毒
Description 最近在生物实验室工作的小T遇到了大麻烦. 由于实验室最近升级的缘故,他的分格实验皿是一个长方体,其尺寸为abc,a.b.c 均为正整数.为了实验的方便,它被划分为abc个单位立 ...
- 【POJ2976】Dropping Tests(分数规划)
[POJ2976]Dropping Tests(分数规划) 题面 Vjudge 翻译在\(Vjudge\)上有(而且很皮) 题解 简单的\(01\)分数规划 需要我们做的是最大化\(\frac{\su ...
- POJ1741:Tree——题解+树分治简要讲解
http://poj.org/problem?id=1741 题目大意:给一棵树,求点对间距离<=k的个数. ———————————————————— 以这道题为例记录一下对于树分治的理解. 树 ...
- HDOJ(HDU).1003 Max Sum (DP)
HDOJ(HDU).1003 Max Sum (DP) 点我挑战题目 算法学习-–动态规划初探 题意分析 给出一段数字序列,求出最大连续子段和.典型的动态规划问题. 用数组a表示存储的数字序列,sum ...
- HDOJ.2084 数塔(DP)
数塔 点我挑战题目 题意分析 DP的思想,自上而下计算. [这几天比较忙 有空补上] 代码总览 /* Title:HDOJ.2084 Author:pengwill Date:2017-1-14 */ ...