且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Python 中更快的套接字

更新时间:2023-11-29 19:51:04

您最新的瓶颈在于 next_intnext_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