首页 游戏 软件 资讯 排行榜 专题
首页
编程语言
Python 3.6与3.11的字典内存对比_Compact Dict布局带来的优化

Python 3.6与3.11的字典内存对比_Compact Dict布局带来的优化

热心网友
90
转载
2026-05-05

Python 3.6+ 字典内存优化揭秘:Compact Dict布局原理与性能实测

Python 3.6及以上版本采用Compact Dict(紧凑字典)布局,通过分离稀疏哈希表与密集键值对数组,显著降低内存占用。实测表明,Python 3.11相比3.6可再节省5%~8%内存,相比3.5及更早版本节省幅度可达25%。

Python 3.6与3.11的字典内存对比_Compact Dict布局带来的优化

免费影视、动漫、音乐、游戏、小说资源长期稳定更新! 👉 点此立即查看 👈

Python 3.6+ 字典内存优化的核心:Compact Dict布局解析

自Python 3.6起,内置字典dict的内部实现经历了重大重构,引入了名为Compact Dict(紧凑字典)的全新内存布局。这一设计在Python 3.11中得到了进一步优化,通过调整内存对齐策略和哈希缓存机制,实现了更高的内存效率。其本质在于将传统字典中混合存储的稀疏哈希表与密集键值对数据彻底分离:新版设计仅维护一个连续的键值对数组,而哈希表中只存储指向该数组的索引。这种分离存储策略有效消除了旧版哈希表中大量存在的空槽位(NULL entries)浪费。以包含十万个字符串到整数映射的字典为例,Python 3.11相较于3.6可额外节省约5%至8%的内存;若与Python 3.5及之前版本对比,总体内存节省接近四分之一。

这种优化并非依赖复杂算法,其核心原理在于用紧凑的索引寻址替代了低效的指针跳转。当然,这种设计在插入新键时可能引入一次额外的间接寻址开销。然而,得益于其对CPU缓存的高度友好性所带来的整体性能增益,这点微乎其微的代价在绝大多数应用场景中完全可以接受。

如何准确测量不同Python版本的字典内存占用?避免sys.getsizeof()的误区

若想亲自验证各版本Python字典的实际内存差异,必须采用科学的测量方法。需要注意的是,内置函数sys.getsizeof()仅返回字典对象自身结构(即对象头与哈希表)的内存大小,并不包含其内部所有键和值对象所占用的空间。要获得准确、可对比的完整内存消耗数据,必须遵循以下步骤:

  • 固定哈希种子以确保结果可复现:通过设置环境变量PYTHONHASHSEED=0或在启动解释器时添加-X hashseed=0参数来禁用哈希随机化。这能保证每次测试的哈希桶分布完全一致。
  • 选用正确的内存测量工具:避免单独使用__sizeof__()。推荐手动递归计算所有关联键值对象的大小,或直接使用专业的第三方库如pympler中的asizeof()函数,它能准确计算整个对象图的内存占用。
  • 控制字典的构建方式:创建测试字典时,优先使用dict(zip(keys, values))一次性生成,而非在循环中通过d[k] = v逐项插入。后者可能因字典的动态扩容机制而产生额外的临时内存开销,影响测量精度。

例如,使用十万个固定长度的字符串键与小型整数值进行测试,在Python 3.6.15与3.11.9环境下,利用asizeof()测得的完整内存占用分别约为12.1 MB与11.3 MB。这一差距主要源于Python 3.11中哈希表的进一步精简以及填充率阈值从2/3提升至3/4所带来的空间利用率提升。

立即学习“Python免费学习笔记(深入)”;

Compact Dict如何保证字典顺序并提升性能?不仅仅是“附带效果”

许多开发者知道Python 3.7起字典的插入顺序成为语言规范。实际上,这一特性并非3.7新增,而是自3.6采用Compact Dict布局后水到渠成的结果:所有键值对按其插入顺序线性存储在紧凑数组中,遍历时只需顺序读取该数组。这带来了以下直接影响:

  • 诸如for k in d:list(d.keys())等遍历操作的时间复杂度稳定为O(n)。得益于极佳的CPU缓存局部性,其执行速度比旧版字典的随机遍历快10%到15%。
  • 性能提升并非在所有操作上均等。例如,popitem(last=True)(弹出最后插入的项)在3.11中比3.6略快,因为它能直接定位数组末端;而popitem(last=False)(弹出第一项)仍需扫描数组头部,因此速度无明显变化。
  • 需要特别留意:如果你的遗留代码或测试用例依赖于“字典键序是随机的”这一隐含假设来实现某些逻辑(如简易的混淆机制),在升级到Python 3.6+后可能会失效。这并非程序错误,而是底层数据结构变更导致的确定性行为改变。

Compact Dict的优势在哪些场景下会被削弱?注意这些潜在开销

尽管紧凑布局在多数情况下能节省内存,但它并非适用于所有场景。在以下几种特定情况下,Python 3.11的字典可能表现出更高的内存占用或稍慢的性能:

  • 使用未正确定义哈希的自定义类作为键:若键是未实现__hash____eq__方法的自定义类对象,Compact Dict仍需存储完整的对象引用。此时,与旧版字典因哈希冲突产生空槽的浪费相比,两者的内存差距可能缩小甚至逆转。
  • 频繁交替执行删除与插入不同键的操作:Python 3.11对已删除槽位的复用逻辑更为积极。然而,如果键的哈希分布极其糟糕(例如发生完全碰撞),仍会触发字典扩容(resize)。值得注意的是,新版字典扩容后的最小尺寸从8增加至32,在某些极端情况下,这可能导致新分配的表比3.6版本下的更大。
  • 使用dict.fromkeys()创建包含大量重复键的字典:虽然3.6与3.11都会对键进行去重,但3.11版本在预分配键数组时可能采用更“积极”的策略。当传入的可迭代对象规模极大(达到千万级别)时,这种预分配机制可能导致临时占用稍多的内存。

归根结底,评估字典内存占用的关键往往不在于容器结构本身,而在于其存储的键值对象——它们的体积、生命周期以及复杂的引用关系。Compact Dict优化的是容器的“外壳”,而对于“壳内”装载的是短小字符串还是包含循环引用的复杂嵌套字典,则无能为力。深刻理解这一点,方能最大化利用新特性的优势,同时有效规避其潜在的局限性。

来源:https://www.php.cn/faq/2311379.html
免责声明: 游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

相关攻略

Python怎样生成填充特定值的多维NumPy数组_利用np.full与形状元组传递
编程语言
Python怎样生成填充特定值的多维NumPy数组_利用np.full与形状元组传递

Python如何高效创建指定形状与填充值的NumPy数组:np full函数详解 在Python数据科学和数值计算中,经常需要快速生成特定形状且所有元素均为相同值的NumPy数组。np full函数正是解决这一需求的理想工具。相比np ones或np zeros只能填充0或1,np full提供了更

热心网友
05.05
Python中如何微调大语言模型LLaMA_借助PEFT框架与LoRA低秩自适应技术
编程语言
Python中如何微调大语言模型LLaMA_借助PEFT框架与LoRA低秩自适应技术

Python中如何微调大语言模型LLaMA:借助PEFT框架与LoRA低秩自适应技术 说到微调LLaMA这类大模型,直接上全参数训练?这可不是个好主意。显存压力大、训练速度慢,还容易陷入过拟合的泥潭。目前来看,PEFT框架配合LoRA技术,算是最为可行的轻量化方案。但问题的关键,从来不是“代码能不能

热心网友
05.05
Flask 2.x怎么兼容原生异步IO库_Python基于async/await改造高并发视图函数
编程语言
Flask 2.x怎么兼容原生异步IO库_Python基于async/await改造高并发视图函数

Flask 2 x 的 async 视图仅在 ASGI 服务器(如 Uvicorn)下有效,WSGI 模式不支持异步;需用 uvicorn 启动、使用异步库、避免阻塞调用,并确保中间件与扩展兼容 async。 Flask 2 x 原生支持 async 视图,但不等于自动支持 asyncio 库的任意

热心网友
05.05
Python大数据量训练报MemoryError怎么搞_设置批处理或启用稀疏矩阵
编程语言
Python大数据量训练报MemoryError怎么搞_设置批处理或启用稀疏矩阵

Python大数据量训练报MemoryError怎么搞_设置批处理或启用稀疏矩阵 训练时直接报 MemoryError,说明数据一次性加载进内存撑爆了 这通常不是模型本身的问题,而是数据处理流程的“内存墙”。Python的默认习惯,比如把整个数据集(无论是numpy ndarray还是pandas

热心网友
05.05
Python如何实现异步的数据清洗 pipeline_基于协程的任务流设计
编程语言
Python如何实现异步的数据清洗 pipeline_基于协程的任务流设计

Python异步数据清洗pipeline实战指南:基于协程的高效任务流设计 asyncio run() 在已有事件循环环境中的正确调用方式 许多开发者在初次构建异步数据清洗流程时,会习惯性地使用 asyncio run(clean_pipeline()) 来启动协程任务。然而当代码运行在Jupyte

热心网友
05.05

最新APP

宝宝过生日
宝宝过生日
应用辅助 04-07
台球世界
台球世界
体育竞技 04-07
解绳子
解绳子
休闲益智 04-07
骑兵冲突
骑兵冲突
棋牌策略 04-07
三国真龙传
三国真龙传
角色扮演 04-07

热门推荐

红米Note11 Pro更新系统需连WiFi吗?
电脑教程
红米Note11 Pro更新系统需连WiFi吗?

红米Note 11 Pro系统升级,为何坚持要求连接Wi-Fi? 当红米Note 11 Pro收到MIUI或澎湃OS的系统更新推送时,官方总会明确提示:整个过程请在Wi-Fi网络环境下完成。这项要求并非随意设定,而是基于清晰的技术与体验考量。一次完整的系统升级包,其大小通常在2GB至4GB之间。如果

热心网友
05.05
小米13ultra有nfc功能吗
电脑教程
小米13ultra有nfc功能吗

小米13 Ultra的NFC功能深度解析:它如何重新定义“全场景智能交互”? 在旗舰手机领域,NFC功能看似已成为标配,但体验却千差万别。小米13 Ultra所搭载的全功能NFC方案,在“全能”与“好用”两个维度上树立了新的标杆。它不仅无缝集成了公交卡模拟、门禁卡复制、数字车钥匙等核心生活服务,更全

热心网友
05.05
嵌入式消毒柜电源插座位置必须外露吗?
电脑教程
嵌入式消毒柜电源插座位置必须外露吗?

嵌入式消毒柜电源插座安装指南:隐蔽式布局提升安全与美观 在规划嵌入式消毒柜的安装方案时,电源插座的布局方式直接影响到最终的整体效果与安全性。正确的做法是避免插座外露,采用隐蔽式安装。根据国家《住宅厨房设计规范》及主流厨电品牌的安装标准,推荐将插座预留在消毒柜后方或侧方的墙体内部,安装高度宜控制在距地

热心网友
05.05
魔音耳机操作说明包含充电指示吗?
电脑教程
魔音耳机操作说明包含充电指示吗?

是的,魔音(Beats)耳机充电状态一目了然,指示灯明确显示 当你为Beats头戴式耳机充电时,如何判断它是否已经充满?答案就藏在机身自带的五段式LED电量指示灯里。在充电过程中,这排指示灯会持续闪烁,实时反馈充电进度。一旦所有五个指示灯全部转为稳定常亮、不再闪烁,即代表电池已完全充满。整个充电周期

热心网友
05.05
博朗剃须刀如何识别型号?
电脑教程
博朗剃须刀如何识别型号?

博朗剃须刀型号全解析:从编码规则到选购技巧的终极指南 面对博朗剃须刀复杂的字母数字组合感到困惑?实际上,其型号命名体系逻辑严谨,是用户选购的核心依据。简单来说,型号首位的数字(1、3、5、7、9)直接代表产品系列,数字越大,通常意味着技术越先进、功能越全面、定位越高端。例如,顶级的9系旗舰机型普遍搭

热心网友
05.05