You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python解析JSON/XML时,对重复键是否执行字符串驻留以节省内存?

问题解答:反序列化大型字典数组时Python是否会对重复键做字符串驻留

核心结论

默认情况下,Python标准库的JSON/XML解析器不会主动对字典的重复键执行字符串驻留优化,但可以通过手动方式实现内存节省。


1. JSON模块(json.load/json.loads)的表现

  • 默认行为:解析过程中,每个字典键都会生成独立的字符串对象——哪怕1000个字典都用"name"作为键,默认也会创建1000个互不关联的"name"字符串实例。这是因为json模块优先保证解析速度,未内置键的驻留逻辑。
  • 手动优化方案:借助sys.intern()和自定义解析钩子,强制重复键共享同一字符串对象。示例代码:
import json
import sys

def intern_dict_keys(obj):
    if isinstance(obj, dict):
        # 对每个键执行驻留,递归处理值
        return {sys.intern(k): intern_dict_keys(v) for k, v in obj.items()}
    elif isinstance(obj, list):
        return [intern_dict_keys(item) for item in obj]
    else:
        return obj

# 加载时应用钩子
with open("large_dataset.json", "r") as f:
    data = json.load(f, object_hook=intern_dict_keys)

2. xml.dom.minidom的表现

  • 默认行为:解析XML后,元素标签名、属性名这类类似“键”的字符串,同样不会自动驻留。相同的标签/属性名会生成多个独立字符串实例。
  • 手动优化方案:遍历DOM树,用sys.intern()处理所有标签和属性名:
import xml.dom.minidom
import sys

def intern_dom_nodes(node):
    if node.nodeType == node.ELEMENT_NODE:
        # 驻留标签名
        node.tagName = sys.intern(node.tagName)
        # 驻留属性名
        processed_attrs = {}
        for attr_name, attr_val in node.attributes.items():
            processed_attrs[sys.intern(attr_name)] = attr_val
        node.attributes = processed_attrs
    # 递归处理子节点
    for child in node.childNodes:
        intern_dom_nodes(child)

# 解析后执行驻留处理
dom = xml.dom.minidom.parse("large_dataset.xml")
intern_dom_nodes(dom)

3. 关于Python字符串驻留的补充

Python解释器本身会对**代码中的字面量小字符串(通常长度<20)**自动驻留,但反序列化时生成的字符串是动态创建的,不在这个自动优化范围内。sys.intern()是手动触发驻留的可靠方式,它会将字符串存入全局驻留池,后续相同字符串会直接返回已有对象的引用。


内容的提问来源于stack exchange,提问作者Vadim Kantorov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 02:12:09