09月17, 2020

36. Dict 的构造

需要注意的是 3.8 版本实现中,Dict 的结构较之前版本有一些调整。

typedef struct {
    PyObject_HEAD    // Python 对象的头部信息
    Py_ssize_t ma_used;  // 字典中元素数量
    uint64_t ma_version_tag; // 全局状态,用来表示所有字典的变化
    PyDictKeysObject *ma_keys; // 字典的 keys,在 combined 模式下也存储 values
    PyObject **ma_values;    // values 数组,仅在 splitted 模式下有效。
} PyDictObject;

其中 PyObject_HEAD 是所有 Python 对象必备的元信息;ma_version_tag 会随着对 Dict 类的操作而自增,表示是否对字典做过修改;ma_keys 和 ma_values 比较特殊,为了降低内存分配调用,字典的 key-value 可能连续的存储在 ma_keys 中,或者 values 单独存储在 ma_values 中。它看起来会是这样子:

image.png

图中也将 PyDictKeysObject 的细节也绘制出来了,就不再赘述。需要注意的是,dk_indices 就是 Dict 的散列表

其中 PyDictKeyEntry 的结构如下,

typedef struct {
    Py_hash_t me_hash;
    PyObject *me_key;
    PyObject *me_value; 
} PyDictKeyEntry;

me_hash 是 me_key 哈希的缓存,减少哈希函数的调用。

这里变量为什么要用 m* 呢?我觉得有可能是 map 的意思,难道早期 Dict 就被称为 Map?有知道的朋友不吝赐教。

本文链接:http://www.thinkinpython.com/post/deep_python_vm_36.html

-- EOF --