在内存中加载大字典的内存使用量大

在内存中加载大字典的内存使用量大,第1张

内存中加载大字典的内存使用量大

很多想法。但是,如果您需要实际帮助,请编辑问题以显示所有代码。还要告诉我们什么是“使用”,它显示已使用的内存,在加载零项的文件时显示的内容,使用的平台以及Python的版本。

您说“这个单词可以是1-5个单词长”。BYTES中关键字段的平均长度是多少?id都是整数吗?如果是,则最小和最大整数是多少?如果不是,则ID的平均长度(以字节为单位)是多少?要启用以上所有功能的交叉检查,6.5M行文件中有多少个字节?

查看您的代码,一个1行的文件

word1,1
将创建一个dict
d['1'] = 'word1'
…难道不是吗?

更新3:更多问题:“单词”如何编码?您确定两个字段中的任何一个都不携带尾随空格吗?

更新4 …您询问“ 如何使用python最有效地将键/值对存储在内存中 ”, 却没人能准确地回答

您有一个168 Mb的文件,包含650万行。每行168 * 1.024 * 2 / 6.5 =
27.1字节。敲掉1个字节的逗号和1个字节的换行符(假设它是一个
x平台),我们每行剩下25个字节。假设“ id”是唯一的,并且看起来像是整数,则假定“
id”的长度为7个字节;这样我们的“字”平均大小为18个字节。这符合您的期望吗?

因此,我们希望在内存中的查找表中存储一个18字节的密钥和一个7字节的值。

让我们假设一个32位CPython 2.6平台。

>>> K = sys.getsizeof('123456789012345678')>>> V = sys.getsizeof('1234567')>>> K, V(42, 31)

注意

sys.getsizeof(str_object) => 24 + len(str_object)

一个回答者提到了元组。请仔细注意以下几点:

>>> sys.getsizeof(())28>>> sys.getsizeof((1,))32>>> sys.getsizeof((1,2))36>>> sys.getsizeof((1,2,3))40>>> sys.getsizeof(("foo", "bar"))36>>> sys.getsizeof(("fooooooooooooooooooooooo", "bar"))36>>>

结论:

sys.getsizeof(tuple_object) => 28 + 4 *len(tuple_object)
…它仅允许指向每个项目的指针,而不允许项目的大小。

对列表的类似分析表明,

sys.getsizeof(list_object) => 36 + 4 *len(list_object)
…再次需要增加项目的大小。还有一个需要考虑的问题:CPython对列表进行整体分配,因此它不必在每个list.append()调用中都调用系统realloc()。对于足够大的大小(例如650万!),超额分配为12.5%,请参阅源(Objects
/ listobject.c)。元组不会完成这种过度分配(它们的大小不会改变)。

这是基于内存的查找表的各种替代命令的成本:

元组列表:

每个元组将为两个元组本身占用36个字节,并为内容加上K和V。因此,其中N个将取N (36 + K + V);
那么您需要一个列表来保存它们,因此我们需要36 + 1.125 * 4
N。

元组列表总数:36 + N *(40.5 + K + v)

那是26 + 113.5 * N(当是650万时 约为709 MB

两个平行的清单:

(36 + 1.125 * 4 * N + K * N)+(36 + 1.125 * 4 * N + V * N)即72 + N *(9 + K + V)

请注意,当N为650万时,40.5 * N和9 * N之差约为200MB。

值存储为int not str:

但这还不是全部。如果这些ID实际上是整数,我们可以将其存储为整数。

>>> sys.getsizeof(1234567)12

每个值对象为12个字节,而不是31个字节。当N为650万时,相差19 * N可以进一步节省约118MB。

使用array.array(’l’)代替(整数)值的列表:

我们可以将这些7位整数存储在array.array(’l’)中。没有int对象,也没有指向它们的指针-
只有4个字节的有符号整数值。奖励:数组仅分配6.25%(对于较大的N)。因此是1.0625 * 4 * N,而不是以前的(1.125 * 4 + 12)*
N,进一步节省了12.25 * N,即76 MB。

因此,我们只有709-200-118-76 = 约315 MB

注意:错误和遗漏除外-我的TZ是0127 :-(



欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5653718.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存