将 python 长整数放入内存,中间没有任何 space
Put python long integers into memory without any space between them
我想将许多大的长整数放入内存,它们之间没有任何 space。如何使用 linux 中的 python 2.7 代码做到这一点?
大长整数都使用相同的位数。总共有大约 4 GB 的数据。留下 spaces 的几位以使每个长整数在内存中使用 8 位的倍数是可以的。我想稍后对它们进行按位运算。
到目前为止,我使用的是 python 列表。但我不确定这是否会在整数之间的内存中留下 space 。 ctypes 有帮助吗?
谢谢。
旧代码使用位数组 (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]
这有效,位数组在内存中没有间隙。但是,位数组按位和在计算机上比原生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 的输出选项。这将避免创建一个新的 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
您可以使用array模块,例如:
import array
ar = array('l', [25L, 26L, 27L])
ar[1] # 26L
space 效率低下的主要原因是 Python 多头的内部结构。假设一个 64 位平台,Python 只使用 32 位中的 30 位来存储一个值。 gmpy2 library provides access to the 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
库。
我想将许多大的长整数放入内存,它们之间没有任何 space。如何使用 linux 中的 python 2.7 代码做到这一点?
大长整数都使用相同的位数。总共有大约 4 GB 的数据。留下 spaces 的几位以使每个长整数在内存中使用 8 位的倍数是可以的。我想稍后对它们进行按位运算。
到目前为止,我使用的是 python 列表。但我不确定这是否会在整数之间的内存中留下 space 。 ctypes 有帮助吗?
谢谢。
旧代码使用位数组 (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]
这有效,位数组在内存中没有间隙。但是,位数组按位和在计算机上比原生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 的输出选项。这将避免创建一个新的 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
您可以使用array模块,例如:
import array
ar = array('l', [25L, 26L, 27L])
ar[1] # 26L
space 效率低下的主要原因是 Python 多头的内部结构。假设一个 64 位平台,Python 只使用 32 位中的 30 位来存储一个值。 gmpy2 library provides access to the 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
库。