内核死后itertools.组合命令

2024-05-23 20:54:55 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用 Python 3.5.2 |Python4.3.0(x86_64)|(默认值,2016年7月2日,17:52:12) [GCC 4.2.1兼容苹果LLVM 4.2(clang-425.0.28)]

我必须运行以下命令

longList = list(combinations(range(2134), 3))

我知道它的长度大约是16亿。当我运行它时,过了一段时间后,我得到消息“内核似乎已经死了。它将自动重新启动。“

使用3而不是2的相同命令运行时没有任何问题:

^{pr2}$

在这种情况下我能/应该怎么做?在


Tags: 命令苹果消息情况range内核x86list
1条回答
网友
1楼 · 发布于 2024-05-23 20:54:55

你的内存可能用完了。快速计算:64位int或指针的大小为8字节。有16亿个组合是元组。每个元组包含三个整数。这意味着您至少需要1.6E9*(1+3)*8B=48GB的内存。在

但是,由于Python的内存模型,您需要的内存比这个多很多倍:每个整数实际上都是一个对象,因此列表中的指针需要1个机器字,而对象本身可能需要3到4个机器字(我不确定具体细节,请阅读CPython源代码了解实际的对象布局)。tuple对象也会有开销。我假设每个对象的头上都有两个词。所以我们必须增加额外的1.6E9*(3+1)*2*8B=95GB的额外开销,总共大约143GB。在

这可以通过使用密集的numpy数组来避免,因为它使用实整数,而不是对象。这消除了integer和tuple对象的所有开销,因此“只”需要1.6E9*3*8B=35GB。在

我想你运行的硬件没有那么多内存。在

您的combinations(..., 2)调用没有问题,因为它只产生大约200万个元组,它的内存需求在兆字节范围(2.2E6*(1+4+2*3)*8B=180MB)。作为一个numpy数组,我们只需要2.2E6*2*8B=33MB。在

那么解决办法是什么呢?在

  • 在规模上,内存模型等低级细节甚至对Python也非常相关
  • 使用numpy可以显著减少内存使用,通常是4倍。如果您使用较小的类型,例如dtype='int16'将是4个减少的额外因素。在
  • 仔细想想,是需要急切地将combinations()转换成一个列表,还是可以懒洋洋地或以较小的块使用迭代器

相关问题 更多 >