2024-05-23 18:18:33 发布
网友
我有一个对象需要用0-3个字符串“标记”(在20个可能的集合中);这些值都是唯一的,顺序无关紧要。唯一需要对标记执行的操作是检查是否存在特定的标记(specific_value in self.tags)。在
specific_value in self.tags
然而,在内存中同时存在大量这样的对象,以至于它超出了我旧计算机的RAM的极限。所以节省几个字节就可以了。在
由于每个对象上的标记太少,我怀疑查找时间会有多重要。但是:在这里使用元组和冻结集有内存区别吗?有没有其他真正的理由用一个来代替另一个呢?在
元组非常紧凑。集合是基于哈希表的,并且依赖于有“空”槽来减少哈希冲突的可能性。在
对于CPython的最新版本,sys._debugmallocstats()显示了许多潜在的有趣信息。在64位Python 3.7.3下:
sys._debugmallocstats()
>>> from sys import _debugmallocstats as d >>> tups = [tuple("abc") for i in range(1000000)]
tuple("abc")创建一个由3个1字符字符串组成的元组,('a', 'b', 'c')。我将编辑几乎所有的输出:
tuple("abc")
('a', 'b', 'c')
因为我们创建了一百万个元组,所以使用1004692个块的size类是我们想要的;每个块消耗72个字节。在
切换到冻结集,输出结果显示,每个冻结集消耗224字节,比原来多3倍多:
>>> tups = [frozenset(t) for t in tups] >>> d() Small block threshold = 512, in 64 size classes. class size num pools blocks in use avail blocks - - - ... 27 224 55561 1000092 6
在这种情况下,你得到的另一个答案恰好给出了相同的结果:
>>> import sys >>> sys.getsizeof(tuple("abc")) 72 >>> sys.getsizeof(frozenset(tuple("abc"))) 224
虽然这通常是正确的,但并非总是如此,因为对象可能需要分配比实际需要更多的字节来满足HW对齐要求。getsizeof()对此一无所知,但_debugmallocstats()显示了Python的小对象分配器实际需要使用的字节数。在
getsizeof()
_debugmallocstats()
例如
>>> sys.getsizeof("a") 50
在32位的机器上,实际上需要使用52个字节,以提供4字节对齐。在64位机器上,当前需要8字节对齐,因此需要使用56字节。在Python3.8(尚未发布)下,在64位机器上需要16字节对齐,而将需要使用64字节。在
但忽略所有这些,元组所需的内存总是比任何具有相同元素数的集合形式都要少,甚至比具有相同元素数的列表还要少。在
如果你想节省内存,考虑一下
dict
sys.getsizeof似乎是您想要的stdlib选项。。。但我对你的整个用例感到不安
sys.getsizeof
stdlib
import sys t = ("foo", "bar", "baz") f = frozenset(("foo","bar","baz")) print(sys.getsizeof(t)) print(sys.getsizeof(f))
https://docs.python.org/3.7/library/sys.html#sys.getsizeof
All built-in objects will return correct results, but this does not have to hold true for third-party extensions as it is implementation specific.
…所以不要对这个解决方案感到舒服
编辑:显然,@TimPeters的答案更正确。。。在
元组非常紧凑。集合是基于哈希表的,并且依赖于有“空”槽来减少哈希冲突的可能性。在
对于CPython的最新版本,
sys._debugmallocstats()
显示了许多潜在的有趣信息。在64位Python 3.7.3下:
^{pr2}$tuple("abc")
创建一个由3个1字符字符串组成的元组,('a', 'b', 'c')
。我将编辑几乎所有的输出:因为我们创建了一百万个元组,所以使用1004692个块的size类是我们想要的;每个块消耗72个字节。在
切换到冻结集,输出结果显示,每个冻结集消耗224字节,比原来多3倍多:
在这种情况下,你得到的另一个答案恰好给出了相同的结果:
虽然这通常是正确的,但并非总是如此,因为对象可能需要分配比实际需要更多的字节来满足HW对齐要求。
getsizeof()
对此一无所知,但_debugmallocstats()
显示了Python的小对象分配器实际需要使用的字节数。在例如
在32位的机器上,实际上需要使用52个字节,以提供4字节对齐。在64位机器上,当前需要8字节对齐,因此需要使用56字节。在Python3.8(尚未发布)下,在64位机器上需要16字节对齐,而将需要使用64字节。在
但忽略所有这些,元组所需的内存总是比任何具有相同元素数的集合形式都要少,甚至比具有相同元素数的列表还要少。在
如果你想节省内存,考虑一下
dict
映射。如果没有标志,则字典中没有条目。在sys.getsizeof
似乎是您想要的stdlib
选项。。。但我对你的整个用例感到不安https://docs.python.org/3.7/library/sys.html#sys.getsizeof
…所以不要对这个解决方案感到舒服
编辑:显然,@TimPeters的答案更正确。。。在
相关问题 更多 >
编程相关推荐