我想分页@mike-mckerns,但我会感谢任何有 Python 的 Klepto 模块(https://pypi.org/project/klepto/)经验的人的回答。
我的情况是我正在运行一个模拟,该模拟涉及生成和记录数以万计的对象,每个对象都是字符串和数值的组合。(我只是想说这些对象不能简单地抽象为例如一个 numpy 数组。)
由于生成的对象数量庞大,我遇到了内存问题。到目前为止,我的解决方案是使用 pickle 将每个实例单独转储到其自己的 pickle 文件中。
问题是这使我的模拟数据分布在 30k 个单独的文件中(每个文件大小约为 5kb)。当试图移动或共享过去模拟的数据时,这很麻烦,总大小是可管理的,但单个文件的数量一直是个问题。
这就是为什么我最终选择了 Klepto 作为可能的解决方案。我认为 file_archive 函数可以让我使用单个文件作为我的“外部”字典,而不是需要为每个实例提供自己的 pickle 文件。
我不太了解该模块的大部分内容,因此我尝试尽可能简单地实现它。我的代码基本上工作如下:
from klepto.archives import file_archive
ExternalObjectDictionary = file_archive('data/EOD.pkl', {}, serialized=True, cached=False)
ObjectCounter = 0
class SimObject:
def __init__(self):
self.name = 'name'
self.data1 = 100
self.data2 = ['pear', 'apple', 'banana']
#(Above values would be passed as arguments by the simulation)
global ExternalObjectDictionary
global ObjectCounter
ObjectCounter += 1
self.ID = ObjectCounter
ExternalObjectDictionary[self.ID] = ObjectData(self.name, self.data1, self.data2)
self.clear_data()
def load_data(self):
global ExternalObjectDictionary
ObjData = ExternalObjectDictionary[self.ID]
self.name = ObjData.name
self.data1 = ObjData.data1
self.data2 = ObjData.data2
def clear_data(self):
self.name = None
self.data1 = None
self.data2 = None
class ObjectData:
def __init__(self, name, data1, data2):
self.name = name
self.data1 = data1
self.data2 = data2
#Simulation would call data in a sequence as follows:
Obj1 = SimObject()
Obj1.load_data()
print(Obj1.name)
Obj1.clear_data()
当不再需要某个对象时,我只需使用del ExternalObjectDictionary[x]
.
就其本身而言,实现似乎运行良好。除了,它最终会比我简单地使用单个泡菜文件时慢 x10 或 x20pickle.dump()
倍pickle.load()
。
我是在使用 Klepto 错误,还是试图从单个文件中转储/加载本质上会比使用单个文件慢得多?我查看了许多选项,Klepto 似乎提供了最直接的从文件读取字典功能来满足我的需要,但也许我误解了如何使用它?
抱歉,如果我的代码示例被简化了,我希望我已经将问题解释得足够清楚,以便有人回应并澄清事情!如果需要,我可以继续使用我当前的 10k 个单独的泡菜文件的解决方案,但如果有可能的替代方法,那就太好了!