我正在尝试从包含大约300万个json序列化对象的文件加载数据集。每个对象都是一个大型嵌套字典,包含各种类型——int、float、list和其他字典。你知道吗
磁盘上的文件大小约为60GB。我有超过128GB的内存,所以我应该能够适应整个设置在内存中。但是,当我使用下面的代码将数据加载到一个大字典中时,已用内存的大小至少增加到110GB(它甚至可能会变大,但我在脚本增长之前就停止了脚本)
当我尝试加载这些数据时,我看到的内存开销是怎么解释的?为什么磁盘上的60GB会转换为内存中的110GB或更多?据我所知,这里唯一的开销应该是为对象创建列表容器,并在结果字典中为这些列表分配一个键名。这不可能占到几乎两倍于数据本身的内存,是吗?你知道吗
def load_by_geohash(file, specificity=7):
results = defaultdict(list)
filename = os.path.join(DATADIR, file)
with open(filename, 'r') as f:
updates = (json.loads(line) for line in f)
for update in updates:
geo_hash = update['geohash'][:specificity]
results[geo_hash].append(update)
return results
是的,很容易做到。考虑一个简单的字符串列表:
在Python中,一切都是一个对象。所以每个(好吧,大多数)单独的对象至少有开销。注意,我的系统中有一个空字符串:
注意,对于
dict
对象,这种差异更大,请考虑:对于一个空的dict来说这是非常巨大的:
现在,有各种各样的选项可以更紧凑地存储数据。但这取决于您的用例。你知道吗
Here是一个与许多词典的内存使用有关的问题。还有一个使用
numpy
数组和namedtuple
对象更紧凑地存储数据的示例。注意,使用namedtuple
对象可能是您所需要的,内存节省可能是巨大的,因为您不需要为键存储实际的字符串对象。如果子字典结构是规则的,我建议用嵌套的namedtuple
对象替换那些嵌套的update
dict。你知道吗相关问题 更多 >
编程相关推荐