【发布时间】:2016-09-02 13:43:36
【问题描述】:
我想将许多大长整数放入内存中,它们之间没有任何空格。如何在 linux 中使用 python 2.7 代码做到这一点?
大长整数都使用相同的位数。总共有大约 4 GB 的数据。保留几位空间以使每个长整数在内存中使用 8 位的倍数是可以的。我想稍后对它们进行按位运算。
到目前为止,我使用的是 python 列表。但我不确定这是否在整数之间留下内存空间。 ctypes 可以帮忙吗?
谢谢。
旧代码使用bitarray (https://pypi.python.org/pypi/bitarray/0.8.1)
import bitarray
data = bitarray.bitarray()
with open('data.bin', 'rb') as f:
data.fromfile(f)
result = data[:750000] & data[750000:750000*2]
这行得通,并且位数组在内存中没有间隙。但是,在计算机上,bitarray 按位运算比原生 python 的长整数按位运算慢约 6 倍。在旧代码中切片位数组并在新代码中访问列表中的元素使用大致相同的时间。
较新的代码:
import cPickle as pickle
with open('data.pickle', 'rb') as f:
data = pickle.load(f)
# data is a list of python's (long) integers
result = data[0] & data[1]
麻木: 在上面的代码中。 result = data[0] & data[1] 创建一个新的长整数。 Numpy 有 numpy.bitwise_and 的 out 选项。这将避免创建一个新的 numpy 数组。然而,numpy 的 bool 数组似乎每个 bool 使用一个字节,而不是每个 bool 一个位。而将 bool 数组转换为 numpy.uint8 数组就可以避免这个问题,但是计算设置位的个数太慢了。
python 的原生数组无法处理大的长整数:
import array
xstr = ''
for i in xrange(750000):
xstr += '1'
x = int(xstr, 2)
ar = array.array('l',[x,x,x])
# OverflowError: Python int too large to convert to C long
【问题讨论】:
-
有一些示例代码来说明您想要实现的目标吗?
-
为什么要关心内存布局?您是否打算与另一个进程共享该内存?
-
嗯。我猜该列表的内存效率低于位数组。有很多数据。实际程序使用多处理库,不修改数据... 第一版程序多次从硬盘读取数据。那个超级慢。
-
你不能在数据上处理一个滑动窗口吗?例如
data1 = bytearray(93750);data2 = bytearray(93750);f.readinto(data1);f.readinto(data2);result = map(operator._and, data1, data2)。这假设这些位被打包到文件中。
标签: python memory ctypes long-integer