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

如何快速保存与加载50GB级别的大型Python字典?

海量Python字典的快速存储与加载方案

一、Pickle的适用性与优化

Pickle是Python原生序列化方案,比JSON高效得多,支持所有Python类型,适配你的场景,但默认配置下并非最优。

  • 优化要点:
    • 使用最高协议版本(pickle.HIGHEST_PROTOCOL),它采用更高效的二进制编码,能大幅减少文件体积和加载时间。
    • 若磁盘空间充足,无需压缩(压缩会增加CPU开销,反而可能拖慢加载速度);若需节省空间,可结合gzip但需权衡速度。
  • 示例代码:
import pickle

# 存储
with open('large_dict.pkl', 'wb') as f:
    pickle.dump(your_large_dict, f, protocol=pickle.HIGHEST_PROTOCOL)

# 加载
with open('large_dict.pkl', 'rb') as f:
    loaded_dict = pickle.load(f)

二、更高效的替代方案

1. Msgpack:轻量二进制序列化库

Msgpack比Pickle更快、文件体积更小,支持跨语言,对数值和列表的序列化效率极高,完全适配你的Int64键和Float32列表值类型。

  • 示例代码:
import msgpack

# 存储
with open('large_dict.msgpack', 'wb') as f:
    packed_data = msgpack.packb(your_large_dict)
    f.write(packed_data)

# 加载
with open('large_dict.msgpack', 'rb') as f:
    loaded_dict = msgpack.unpackb(f.read())

注:Msgpack默认将Python float序列化为64位,若需严格存储Float32,可先将值转换为numpy.float32类型后再序列化,加载时自动还原即可。

2. 自定义二进制格式(性能最优)

直接基于二进制格式存储,结合内存映射(mmap)和numpy解析,能达到磁盘IO的极限速度,几乎无序列化解析开销,但需要手动实现读写逻辑。

  • 核心思路:按「键数量→每个键(Int64)→值列表长度→值列表的Float32二进制数据」的顺序存储,加载时直接通过内存映射读取并解析。
  • 示例代码:
import struct
import numpy as np
import mmap

# 存储
with open('large_dict.bin', 'wb') as f:
    # 写入键的总数(无符号64位)
    f.write(struct.pack('Q', len(your_large_dict)))
    for key, value_list in your_large_dict.items():
        # 写入Int64类型的键
        f.write(struct.pack('q', key))
        # 写入值列表的长度
        val_count = len(value_list)
        f.write(struct.pack('I', val_count))
        # 将值列表转为Float32二进制并写入
        flat_vals = np.array(value_list, dtype=np.float32).flatten()
        f.write(flat_vals.tobytes())

# 加载
with open('large_dict.bin', 'rb') as f:
    with mmap.mmap(f.fileno(), length=0, access=mmap.ACCESS_READ) as mm:
        ptr = 0
        # 读取键的总数
        num_keys, = struct.unpack_from('Q', mm, ptr)
        ptr += struct.calcsize('Q')
        loaded_dict = {}
        for _ in range(num_keys):
            # 读取键
            key, = struct.unpack_from('q', mm, ptr)
            ptr += struct.calcsize('q')
            # 读取值列表长度
            val_count, = struct.unpack_from('I', mm, ptr)
            ptr += struct.calcsize('I')
            # 读取Float32数据并恢复为列表
            data_len = val_count * 3
            flat_data = np.frombuffer(mm, dtype=np.float32, count=data_len, offset=ptr)
            ptr += data_len * 4  # 每个Float32占4字节
            loaded_dict[key] = flat_data.reshape(-1, 3).tolist()

3. 内存缓存服务(如Redis)

若程序频繁重启,可将字典持久化到Redis中,启动时直接从Redis加载到内存,速度远快于磁盘读取。Redis支持Int64键和二进制值,可将值序列化为Msgpack或自定义二进制后存储。

三、方案选择建议

  • 追求简单易用:优先选Msgpack,实现成本低,性能远超Pickle和JSON。
  • 追求极致性能:选自定义二进制格式+内存映射,加载速度接近磁盘读取极限。
  • 频繁重启场景:搭配Redis,彻底解决启动加载慢的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 04:05:54