struct模块之前看过一些,也看到过说是struct模块的性能不行,今天在网上看到了另外一篇文章,先转过来待后面使用时研究下:
================================华丽的转载分割线==========================================
转载来源: 文章来自http://www.cnblogs.com/coser/archive/2011/12/17/2291160.html这篇文章
================================再割====================================================
下面是部分文章原文:感觉其中ctypes.create_string_buffer这个蛮好的,没研究过,还是没学到家啊。。。。
3、利用buffer,使用pack_into和unpack_from方法
使用二进制打包数据的场景大部分都是对性能要求比较高的使用环境。而在上面提到的pack方法都是对输入数据进行操作后重新创建了一个内存空间用于返回,也就是说我们每次pack都会在内存中分配出相应的内存资源,这有时是一种很大的性能浪费。struct模块还提供了pack_into() 和 unpack_from()的方法用来解决这样的问题,也就是对一个已经提前分配好的buffer进行字节的填充,而不会每次都产生一个新对象对字节进行存储。
import struct
import binascii
import ctypes
values = (1, 'abc', 2.7)
s = struct.Struct('I3sf')
prebuffer = ctypes.create_string_buffer(s.size)
print 'Before :',binascii.hexlify(prebuffer)
s.pack_into(prebuffer,0,*values)
print 'After pack:',binascii.hexlify(prebuffer)
unpacked = s.unpack_from(prebuffer,0)
print 'After unpack:',unpacked
输出:
Before : 000000000000000000000000
After pack: 0100000061626300cdcc2c40
After unpack: (1, 'abc', 2.700000047683716)
对比使用pack方法打包,pack_into 方法一直是在对prebuffer对象进行操作,没有产生多余的内存浪费。另外需要注意的一点是,pack_into和unpack_from方法均是对string buffer对象进行操作,并提供了offset参数,用户可以通过指定相应的offset,使相应的处理变得更加灵活。例如,我们可以把多个对象pack到一个buffer里面,然后通过指定不同的offset进行unpack:
import struct
import binascii
import ctypes
values1 = (1, 'abc', 2.7)
values2 = ('defg',101)
s1 = struct.Struct('I3sf')
s2 = struct.Struct('4sI')
prebuffer = ctypes.create_string_buffer(s1.size+s2.size)
print 'Before :',binascii.hexlify(prebuffer)
s1.pack_into(prebuffer,0,*values1)
s2.pack_into(prebuffer,s1.size,*values2)
print 'After pack:',binascii.hexlify(prebuffer)
print s1.unpack_from(prebuffer,0)
print s2.unpack_from(prebuffer,s1.size)
输出:
Before : 0000000000000000000000000000000000000000
After pack: 0100000061626300cdcc2c406465666765000000
(1, 'abc', 2.700000047683716)
('defg', 101)