📜  使用哈希表的Python 3.6 字典实现

📅  最后修改于: 2022-05-13 01:55:48.290000             🧑  作者: Mango

使用哈希表的Python 3.6 字典实现

Python中的字典是数据值的集合,用于像地图一样存储数据值,与其他仅将单个值作为元素保存的数据类型不同,字典包含键:值对。字典中提供了键值,使其更加优化。字典中的每个键值对都用冒号分隔:,而每个键都用“逗号”分隔。要了解有关词典的更多信息,请单击此处。

根据 Raymond Hettinger 的提议,与Python v.3.5 或更低版本相比,新的 dict()函数的内存使用量减少了 20% 到 25%。它依赖于 Raymond Hettinger 提出的保语义。此实现使字典更紧凑,并提供更快的迭代。

早期版本中字典的内存布局不必要地低效。它由一个 24 字节条目的稀疏表组成,其中存储了散列值、键指针和值指针。 3.5 及更低版本中字典的内存布局被实现为存储在单个稀疏表中。

例子:

for the below dictionary:

d = {'banana':'yellow', 'grapes':'green', 'apple':'red'}

used to store as:

    entries = [['--', '--', '--'],
               [-5850766811922200084, 'grapes', 'green'],
               ['--', '--', '--'],
               ['--', '--', '--'],
               ['--', '--', '--'],
               [2247849978273412954, 'banana', 'yellow'],
               ['--', '--', '--'],
               [-2069363430498323624, 'apple', 'red']]

相反,在新的 dict() 实现中,数据现在被组织在一个密集表中,该表由一个稀疏索引表引用,如下所示:

indices  = [None, 1, None, None, None, 0, None, 2]
 entries = [[2247849978273412954, 'banana', 'yellow']
             [-5850766811922200084, 'grapes', 'green'],
             [-2069363430498323624, 'apple', 'red']]

重要的是要注意,在新的 dict() 实现中,只有数据布局发生了变化,哈希表算法没有变化。碰撞静力学和表搜索顺序都没有改变。

dict() 的这种新实现被认为可以根据 getdictionary 的大小显着压缩字典以节省内存。小型词典可以从中获得最大的好处。

对于具有 n 个条目的大小为 t 的稀疏表,大小为:

curr_size = 24 * t
new_size = 24 * n + sizeof(index) * t

在上面的示例香蕉/葡萄/苹果中,前一个实现的大小为 192 字节(八个 24 字节条目),后一个实现的大小为 90 字节(三个 24 字节条目和八个 1 字节索引)。这表明字典大小压缩了大约 58%。

除了节省内存,新的内存布局让迭代更快。现在,像 Keys()、items() 和 values 这样的函数可以在密集表上循环,而不必跳过空槽,这与旧的实现不同。这种新实现的其他好处是更好的缓存利用率、更快的大小调整和更少的内存接触。