保存和加载大型字典的最快且最有效的方法

Tes*_*est 6 python dictionary pickle

我有个问题。我有一个巨大的dict. 我想保存并加载这个巨大的字典。但不幸的是我得到了一个MemoryError. 字典不应该太大。从数据库中读取的内容约为 4GB。我现在想保存这个字典并读出它。但是,它应该是高效的(不会消耗更多内存)并且不会花费太长时间。

目前有哪些选择?我无法进一步了解pickle,出现内存错误。我还剩 200GB 可用磁盘空间。

我查看了用 Python 保存和加载大型字典的最快方法以及其他一些问题和博客。

import pickle
from pathlib import Path

def save_file_as_pickle(file, filename, path=os.path.join(os.getcwd(), 'dict')):
    Path(path).mkdir(parents=True, exist_ok=True)
    pickle.dump( file, open( os.path.join(path, str(filename+'.pickle')), "wb" ))

save_file_as_pickle(dict, "dict")

[OUT]

---------------------------------------------------------------------------
MemoryError                               Traceback (most recent call last)
<timed eval> in <module>

~\AppData\Local\Temp/ipykernel_1532/54965140.py in save_file_as_pickle(file, filename, path)
      1 def save_file_as_pickle(file, filename, path=os.path.join(os.getcwd(), 'dict')):
      2     Path(path).mkdir(parents=True, exist_ok=True)
----> 3     pickle.dump( file, open( os.path.join(path, str(filename+'.pickle')), "wb" ))

MemoryError: 
Run Code Online (Sandbox Code Playgroud)

什么有效,但花了 1 小时并且使用了 26GB 空间磁盘

with open('data.json', 'w', encoding='utf-8') as f:
    json.dump(dict, f, ensure_ascii=False, indent=4)
Run Code Online (Sandbox Code Playgroud)

我查了一下我的字典有多大(以字节为单位)。我遇到了这个问题How to Know bytes size of python object like arrays and dictionaries? - 简单的方法,它显示该字典只有 8448728 字节。

import sys
sys.getsizeof(dict)
[OUT] 8448728
Run Code Online (Sandbox Code Playgroud)

我的数据是什么样的(示例)

{
'_key': '1',
 'group': 'test',
 'data': {},
 'type': '',
 'code': '007',
 'conType': '1',
 'flag': None,
 'createdAt': '2021',
 'currency': 'EUR',
 'detail': {
        'selector': {
            'number': '12312',
            'isTrue': True,
            'requirements': [{
                'type': 'customer',
                'requirement': '1'}]
            }
        }   

 'identCode': [],
 }
Run Code Online (Sandbox Code Playgroud)

Cor*_*bie 3

有两种方法可以提高酸洗的性能

  1. 在酸洗时禁用垃圾收集器以加快速度
  2. 用于gzip生成压缩输出文件

尝试一下:

import gc
import gzip
import os
import pickle
from pathlib import Path


def save_file_as_pickle(file, filename, path=os.path.join(os.getcwd(), "dict")):
    Path(path).mkdir(parents=True, exist_ok=True)
    file_path = os.path.join(path, str(filename + ".pickle"))

    gc.disable()
    try:
        gc.collect()
        with gzip.open(file_path, "wb") as fp:
            pickle.dump(file, fp)
    finally:
        gc.enable()


save_file_as_pickle(my_dict, "dict")
Run Code Online (Sandbox Code Playgroud)

  • 任何这样的模式都应该将 `gc.enable` 调用放在 `finally` 块中。 (3认同)