更新时间:2023-11-29 19:51:04
您最新的瓶颈在于 next_int
和 next_float
因为您从 bytearray 创建了中间字符串
并且因为您一次只解压一个值.
Your latest bottleneck is in next_int
and next_float
because you create intermediate strings from the bytearray
and because you only unpack one value at a time.
struct
模块有一个 unpack_from
,它接受一个缓冲区和一个偏移量.这更有效,因为不需要从您的 bytearray
创建一个中间字符串:
The struct
module has an unpack_from
that takes a buffer and an offset. This is more efficient because there is no need to create an intermediate string from your bytearray
:
def next_int(self):
self.recv_buf_i += 4
return struct.unpack_from("i", self.recv_buf, self.recv_buf_i-4)[0]
此外,struct
模块一次可以解压多个值.目前,您为每个值从 Python 调用 C(通过模块).通过减少调用它的次数并让它在每次调用时做更多的工作,你会得到更好的服务:
Additionally, struct
module can unpack more than one value at a time. Currently, you call from Python to C (via the module) for each value. You would be better served by calling it fewer times and letting it do more work on each call:
def next_chunk(self, fmt): # fmt can be a group such as "iifff"
sz = struct.calcsize(fmt)
self.recv_buf_i += sz
return struct.unpack_from(fmt, self.recv_buf, self.recv_buf_i-sz)
如果您知道 fmt
将始终是 4 字节整数和浮点数,您可以将 struct.calcsize(fmt)
替换为 4 * len(fmt)代码>.
If you know that fmt
will always be 4 byte integers and floats you can replace struct.calcsize(fmt)
with 4 * len(fmt)
.
最后,作为偏好,我认为这读起来更干净:
Finally, as a matter of preference I think this reads more cleanly:
def next_chunk(self, fmt):
sz = struct.calcsize(fmt)
chunk = struct.unpack_from(fmt, self.recv_buf, self.recv_buf_i)
self.recv_buf_i += sz
return chunk