您的位置:首页 > 编程语言 > Python开发

看书 Python 源码分析笔记 (二)

2015-12-18 00:00 639 查看

第二章 Python 中的整数对象

初识 PyIntObject 对象

整数被创建为 PyIntObject (类)的实例.
整数对象是一种不可变对象 (immutable), 即一旦创建, 该对象内部的那个 ival 值不变化.
Python 中 string 也是不可变对象. (ruby 中 string 是可变的...)

整数使用频繁, 即 new/delete 很频繁, 如何提高效率? --- python 使用对象缓冲池机制.

PyIntObject 的元信息见文件 intobject.c.

整数做加法时, 如果溢出会产生 PyLongObject.

(其它略...)

PyIntObject 对象的创建和维护

创建整数的 3 条途径(简单了解一下即可, 细节略):
1. PyInt_FromLong(long ival)
2. PyInt_FromString(char *s ...)
3. PyInt_FromUnicode(UNICODE ...)

对于小整数对象被放到对象池中. 这样(它们)就不需要频繁的 malloc/free 了.
这个小整数对象池在初始化函数 _PyInt_Init() 中实现.

对于大整数对象, Python 提供一块内存空间, 由它们轮流使用. 在 intobject.c 中.

struct PyInt_Block {
PyInt_Block *next;   // 构成链表.
PyIntObject objects[NUM_OF_INTOBJS];  // 可以放数个整数对象.
}

PyInt_Block *block_list;  // 维护整个 _intblock 链表.
PyIntObject *free_list;   // 指向第一个可分配的 int 对象.


所以 这里是一种典型的小块内存分配策略. (因此细节不用再看了)

=================================================================

第三章 Python 中的字符串对象

前面 int 对象是固定长度的对象, 本章学习的 string 对象是变长的(var-size), 但内容是不可变的(immutable).

对应 string 的类为 PyStringObject:

struct PyStringObject {
int ref_count;
PyType_Object *ob_type;  // = &PyString_Type.
int ob_size;
// 以上是 PyVarObject 头部, 下面是 string 对象数据.
int ob_shash;     // 缓存此字符串的 hash 值.
int ob_sstate;    // interned 标志.
char ob_sval[1];  // 变长的字符串数据在这里, 包含 ob_size+1 个元素, 以 \0 结束.
};

根据结构看, ob_sval[] 是变长数组, 预计是根据字符串长度动态分配这个对象大小的.

Python 内部所有变长对象使用 ob_size 机制.
Python 注释显示, 预存字符串 hash 值和 intern 机制将 python 虚拟机的执行效率提升了 20%. (空间换时间)

PyString_Type 中 tp_as_number, tp_as_sequence, tp_as_mapping 都被设置, 故而 string 支持这三种操作.

创建 PyStringObject 对象

类似于 int 对象, 函数 PyObject *PyString_FromString(const char *str) 可创建一个 Python 字符串对象.
别的类似函数可看做不同的 String 构造函数.

字符串对象的 intern 机制

Python 对长度为 0,1 的字符串提供特别动作: intern. (书上翻译为 `共享', 有的地方翻译为 `拘留' ...)

实现为使用一个内部(static的) dict 来保存所有 interned 字符串, 该 string 同时作为 key 和 value 在 dict 中.

字符缓冲池

Python 对单个字符的字符串也提供了对象池. (stringobject.c 用 characters[UCHAR_MAX+1] 数组实现)

PyStringObject 效率相关问题

用 '+' 运算符连接字符串在 Python 中极其低效, 官方推荐做法用 string.join() 进行连接操作.
方法是先计算总的所需空间, 然后一次性分配结果字符串, 然后复制...

=================================================================

第四章 Python 中的 List 对象

PyListObject 是 Python 提供的列表实现类. 与 STL 中的 vector 比较相似.

PyListObject 对象

可看作是 vector<PyObject *>, 可插入, 添加, 删除元素.

struct PyListObject {
PyObject_VAR_HEAD;   // 变长 Python 对象头部. ob_size 应是元素数量.
PyOjbect **ob_item;  // 列表实现.
int allocated;       // 总容量 (capacity).
};

根据字段看, 是类似于 vector 的机理.

PyListObject 对象的创建与维护

函数 PyList_New() 用于创建 list 对象. (可看做是 PyListObject.ctor() 构造函数).

内部使用一个大小为 MAXFREELISTS(=80) 的数组做对象池, 以减少 malloc/free 调用.

列表的对象 get/set[index], insert(), append(), remove() 等方法实现与 vector 相似, 因此细节略.

PyListObject 对象缓冲池

即 free_lists[] 数组的维护.

(本篇 END, 下次接着学习)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: