将python长整数放入内存中,它们之间没有任何空格

时间:2016-05-07 15:04:45

标签: python memory ctypes long-integer

我想将许多大的长整数放入内存中,它们之间没有任何空格。如何在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在内存中没有间隙。但是,bitarray按位并且比计算机上的本机python的长整数按位运算慢6倍。在旧代码中切换bitarray并在较新代码中访问列表中的元素使用的时间大致相同。

较新的代码:

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]

numpy的: 在上面的代码中。 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

2 个答案:

答案 0 :(得分:3)

您可以使用array模块,例如:

new XMLHTTPRequest()

答案 1 :(得分:2)

空间效率低下的主要原因是Python的内部结构很长。假设一个64位平台,Python只使用32位中的30位来存储一个值。 gmpy2库提供对GMP(GNU多精度算术库)的访问。 gmpy2.mpz类型的内部结构使用所有可用位。以下是存储750000位值的大小差异。

>>> import gmpy2
>>> import sys
>>> a=long('1'*750000, 2)
>>> sys.getsizeof(a)
100024
>>> sys.getsizeof(gmpy2.mpz(a))
93792

使用``gmpy2.mpz`的&操作也明显更快。

$ python -m timeit -s "a=long('A'*93750,16);b=long('7'*93750)" "c=a & b"
100000 loops, best of 3: 7.78 usec per loop
$ python -m timeit -s "import gmpy2;a=gmpy2.mpz('A'*93750,16);b=gmpy2.mpz('7'*93750)" "c=a & b"
100000 loops, best of 3: 4.44 usec per loop

如果您的所有操作都就位,gmpy2.xmpz类型允许更改实例的内部值而无需创建新实例。只要所有操作都是即时的,它就会更快。

$ python -m timeit -s "import gmpy2;a=gmpy2.xmpz('A'*93750,16);b=gmpy2.xmpz('7'*93750)" "a &= b"
100000 loops, best of 3: 3.31 usec per loop

免责声明:我维护gmpy2库。