我在Pyrobuf页面上看到了这个示例代码,用于序列化整数,比通过struct.pack
快〜3倍:
def ser2():
cdef int x = 42
return (<char *>&x)[:sizeof(int)]
我想知道如何为一组整数做这件事。
我看到cython有int[:]
和array.array
类型,但我仍然不明白如何获取整数列表,例如,通过{{1}获得相同(但更快)的结果}。 struct.pack('i', *num_list)
对我来说似乎没有那么快,我想知道应该怎么做。
答案 0 :(得分:2)
我假设你想要加速以下(Python3):
import struct
lst=list(range(100)) #any other size
struct.pack('i'*len(lst), *lst)
没有struct
和cython你可以在python中实现它:
import array
bytes(array.array('i', lst))
然而,这比struct
- 模块:慢一些
>>> %timeit struct.pack('i'*len(lst), *lst)
2.38 µs ± 9.48 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
>>> %timeit bytes(array.array('i',lst))
3.94 µs ± 92 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
但是,cython可用于加速array
的创建,文档请参阅here(arrays)和here(str/bytes):
%%cython
import array
from cpython cimport array
def ser_int_list(lst):
cdef Py_ssize_t n=len(lst)
cdef array.array res=array.array('i')
array.resize(res, n) #preallocate memory
for i in range(n):
res.data.as_ints[i]=lst[i] #lst.__get__() needs Python-Integer, so let i be a python-integer (not cdef)
return res.data.as_chars[:n*sizeof(int)] # str for python2, bytes for python3
时间表显示以下表现:
#list_size struct-code cython-code speed-up
1 343 ns 238 ns 1.5
10 619 ns 283 ns 2
100 2.38 µs 2.38 µs 3.5
1000 21.6 µs 5.11 µs 4
10000 266 µs 47.5 µs 5.5
即。 cython提供了一些加速,从1.5
小列表到5.5
大列表。
可能这可以进一步调整,但我希望你能得到这个想法。
测试代码:
import struct
for n in [1, 10,10**2, 10**3, 10**4]:
print ("N=",n)
lst=list(range(n))
print("struct:")
%timeit struct.pack('i'*len(lst), *lst)
print("cython:")
%timeit ser_int_list(lst)