Я пытаюсь ускорить обработку сокетов в python, используя буфер / очередь ниже реализации для циклического буфера, которую я использую, чтобы прочитать максимальный размер из сокета localhost, используемого для IPC
class BufferHandling:
def __init__(self, buffer_size, max_chunk_size):
self._read_index = 0
self._write_index = 0
self._buffer = bytearray(buffer_size)
self._mem_view = memoryview(self._buffer)
self._max_size = max_chunk_size
def fill_from_socket(self, _socket):
logging.debug("2 fill: write index %s , read_index %s", self._write_index , self._read_index)
if self._read_index > self._write_index:
if self._read_index - self._write_index < self._max_size:
raise RuntimeError("no place to write in buffer")
ret = _socket.recv_into(self._mem_view[self._write_index:], self._max_size)
self._write_index += ret
#logging.debug("1 recv_from return with %s, write index %s", ret, self._write_index)
return
# write >= read
_1st_write_size = len(self._mem_view) - self._write_index
_2nd_write_size = self._read_index
if _1st_write_size + _2nd_write_size < self._max_size:
raise RuntimeError("no place to write in buffer")
if _1st_write_size >= self._max_size:
ret = _socket.recv_into(self._mem_view[self._write_index:], self._max_size)
self._write_index += ret
#logging.debug("2 recv_from return with %s , write index %s", ret, self._write_index)
return
# clear some room ...
self._mem_view[:self._write_index - self._read_index] = self._mem_view[self._read_index: self._write_index]
self._write_index = self._write_index - self._read_index
self._read_index = 0
ret = _socket.recv_into(self._mem_view[self._write_index:], self._max_size)
self._write_index += ret
logging.debug("3 recv_from return with %s, write index %s", ret, self._write_index)
"""
# read data from cyclic buffer
# if data found , return data according to _to_read size
# else return empty string
"""
def read_from_buffer(self, _to_read):
logging.debug("1 write_index %s , read_index %s , _to_read %s", self._write_index, self._read_index, _to_read)
if self._read_index > self._write_index:
_1st_read_size = len(self._mem_view) - self._read_index
_2nd_read_size = self._write_index
if _1st_read_size >= _to_read:
data = self._buffer[self._read_index: self._read_index + _to_read]
self._read_index += _to_read
else:
data = self._buffer[self._read_index:] + self._buffer[:_to_read - _1st_read_size]
self._read_index = _to_read - _1st_read_size
else: # write >= read
_read_less = min(_to_read, self._write_index - self._read_index)
# if self._write_index - self._read_index < _to_read:
# logging.debug("2 write_index %s , read_index %s , _to_read %s", self._write_index,self._read_index,_to_read)
# #return None
logging.debug("2 write_index %s , read_index %s , _to_read %s, _read %s", self._write_index, self._read_index, _to_read, _read_less)
data = self._buffer[self._read_index: self._read_index + _read_less]
self._read_index += _read_less
return data
Я использую его следующим образом:
self.__buffer = BufferHandling(self.__LOCALHOST_SOCKET_BUFFER_LEN * 4,
self.__LOCALHOST_SOCKET_BUFFER_LEN)
data = self.__buffer.read_from_buffer(_to_read)
if len(data) < _to_read:
self._selector.select(rlist = [self.__connection], elist = [self.__connection])
self.__buffer.fill_from_socket(self.__connection)
data += self.__buffer.read_from_buffer(_to_read)
После того, как я столкнулся со многими проблемами, у меня возник вопрос: есть ли более Pythonic
способ получить такой же эффект?или, может быть, предложить более «чистый» способ получить какую-то форму io buffering