Python 有序的字典,更快迭代速度和更紧凑的数据结构

Python 有序的字典,更快迭代速度和更紧凑的数据结构

 

原文链接:https://mail.python.org/pipermail/python-dev/2012-December/123028.html

 

Python3.6 之后字典的数据结构已修改为如下结构。

 

字典的当前内存布局

不必要地低效。它有一个

包含散列值,键指针

和值指针的24字节条目的稀疏表。

 

相反,24字节条目应存储在

由稀疏索引表引用的密集表中。

 

 

比如,如下一个字典:

 

    d = {'timmy': 'red', 'barry': 'green', 'guido': 'blue'}

 

Python<=3.5 这样存储:

 

    entries = [['--', '--', '--'],

               [-8522787127447073495, 'barry', 'green'],

               ['--', '--', '--'],

               ['--', '--', '--'],

               ['--', '--', '--'],

               [-9092791511155847987, 'timmy', 'red'],

               ['--', '--', '--'],

               [-6480567542315338377, 'guido', 'blue']]

 

相反,更合理的存储结构如下Python>=3.6:

 

    indices =  [None, 1, None, None, None, 0, None, 2]

    entries =  [[-9092791511155847987, 'timmy', 'red'],

                [-8522787127447073495, 'barry', 'green'],

                [-6480567542315338377, 'guido', 'blue']]

 

只需要更改数据布局。哈希表

算法将保持不变。

将保留所有当前优化,包括密钥共享

dicts和仅字符串dicts的自定义查找功能

。哈希函数没有变化,

 

节省的内存很大(

压缩率从30%到95%,具体取决于表的填充程度)。

小的dicts(大小0,1或2)获得最大的好处。

 

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

    curr_size = 24 * t

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

 

在上面的timmy / barry / guido示例中,当前

大小为192字节(8 24字节条目)和新

大小是80字节(三个24字节条目加上八个

1字节索引)。这提供了58%的压缩。

 

注意,

对于小的dicts,sizeof(index)索引可以小到单个字节,对于较大的

dicts,sizeof索引 可以小到两个字节,对于巨大的dict,可以是sizeof(py_ssize_t)。

除了节省空间外,新的内存布局

使迭代更快。目前,keys(),values和

items()遍历稀疏表,跳过

哈希表中的空闲槽。现在,keys / values / items可以

使用更少的内存

访问直接在密集表上循环。

 

另一个好处是调整大小更快,

触及更少的内存。目前,

调整大小期间移动或复制每个散列/键/值条目。在新布局中,仅

更新索引。在大多数情况下,散列/键/值条目

永远不会移动(除了偶尔交换以填充

删除留下的空洞)。

 

随着内存占用减少,我们也可以期待

更好的缓存利用率 

 

对于那些想要尝试设计的人来说,

这里有一个纯粹的Python概念验证:

 http://code.activestate.com/recipes/578375

YMMV:请记住,上面的大小静态假定

使用64-构建位Py_ssize_t和64位指针。

其他

版本的空间节省百分比略有不同。另外,请注意,在许多应用中,

数据的大小决定了容器的大小(即

一桶水的重量主要是水,

而不是水桶)。

雷蒙德

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值