Python 根据底层系统架构自动分配整数。不幸的是,我有一个巨大的数据集,需要完全加载到内存中。
那么,有没有办法强制 Python 只对某些整数使用 2 个字节(相当于 C++ 'short')?
Python 根据底层系统架构自动分配整数。不幸的是,我有一个巨大的数据集,需要完全加载到内存中。
那么,有没有办法强制 Python 只对某些整数使用 2 个字节(相当于 C++ 'short')?
没有。但是您可以在数组中使用短整数:
from array import array
a = array("h") # h = signed short, H = unsigned short
只要该值保留在该数组中,它将是一个短整数。
感谢 Armin 指出“数组”模块。我还发现了将 c 风格的结构打包成字符串的“struct”模块:
从文档(https://docs.python.org/library/struct.html):
>>> from struct import *
>>> pack('hhl', 1, 2, 3)
'\x00\x01\x00\x02\x00\x00\x00\x03'
>>> unpack('hhl', '\x00\x01\x00\x02\x00\x00\x00\x03')
(1, 2, 3)
>>> calcsize('hhl')
8
Armin 对阵列模块的建议可能是最好的。两种可能的选择:
值得一提的是,Python 整数对象不是 4 个字节——还有额外的开销。因此,如果您有大量的短裤,那么您可以通过以某种方式(例如数组模块)使用 C 短裤来为每个号码节省两个以上的字节。
不久前,我不得不在内存中保留大量整数,并且带有整数键和值的字典太大(我有 1GB 可用于数据结构 IIRC)。我改用 IIBTree(来自 ZODB)并设法适应它。(IIBTree 中的整数是真正的 C 整数,而不是 Python 整数,当数字大于 32 位时,我将自动切换到 IOBTree)。
您可以将 NumyPy 的 int 用作 np.int8 或 np.int16。
您还可以将多个任意大小的整数存储在一个大整数中。
例如如下所示,在 64 位 x86 系统上的 python3 中,1024 位占用 164 字节的内存存储。这意味着平均一个字节可以存储大约 6.24 位。如果你使用更大的整数,你可以获得更高的位存储密度。例如,每字节大约 7.50 位,2**20 位宽整数。
显然,您将需要一些包装逻辑来访问存储在较大整数中的各个短数字,这很容易实现。
这种方法的一个问题是您的数据访问会因为使用大整数运算而减慢。
如果您一次访问大量连续存储的整数以最小化对大整数的访问,那么对长整数的较慢访问将不是问题。
我想使用 numpy 会更容易。
>>> a = 2**1024
>>> sys.getsizeof(a)
164
>>> 1024/164
6.2439024390243905
>>> a = 2**(2**20)
>>> sys.getsizeof(a)
139836
>>> 2**20 / 139836
7.49861266054521
在 python 中使用 bytearray 基本上是一个 C unsigned char 数组,这将是一个比使用大整数更好的解决方案。操作字节数组没有开销,并且与大整数相比,它的存储开销要少得多。使用 bytearrays 可以获得每字节 7.99+ 位的存储密度。
>>> import sys
>>> a = bytearray(2**32)
>>> sys.getsizeof(a)
4294967353
>>> 8 * 2**32 / 4294967353
7.999999893829228