Schnellere Sockets in Python

Ich habe einen Client in Python für einen Server geschrieben, der über LAN funktioniert. Ein Teil des Algorithmus verwendet das Lesen von Sockets intensiv und es wird ungefähr 3-6 mal langsamer ausgeführt alsfast das gleiche geschrieben in C ++. Welche Lösungen gibt es, um das Lesen von Python-Sockets zu beschleunigen?

Ich habe einige einfache Puffer implementiert, und meine Klasse für die Arbeit mit Sockets sieht folgendermaßen aus:

import socket
import struct

class Sock():
    def __init__(self):
        self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.recv_buf = b''
        self.send_buf = b''

    def connect(self):
        self.s.connect(('127.0.0.1', 6666))

    def close(self):
        self.s.close()

    def recv(self, lngth):
        while len(self.recv_buf) < lngth:
                self.recv_buf += self.s.recv(lngth - len(self.recv_buf))

        res = self.recv_buf[-lngth:]
        self.recv_buf = self.recv_buf[:-lngth]
        return res

    def next_int(self):
        return struct.unpack("i", self.recv(4))[0]

    def next_float(self):
        return struct.unpack("f", self.recv(4))[0]

    def write_int(self, i):
        self.send_buf += struct.pack('i', i)

    def write_float(self, f):
        self.send_buf += struct.pack('f', f)

    def flush(self):
        self.s.sendall(self.send_buf)
        self.send_buf = b''

P .: Die Profilerstellung zeigt auch, dass die meiste Zeit mit dem Lesen von Sockets verbracht wird.

Bearbeiten: Da Daten in Blöcken mit bekannter Größe empfangen werden, kann ich den gesamten Block auf einmal lesen. Also habe ich meinen Code folgendermaßen geändert:

class Sock():
    def __init__(self):
        self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.send_buf = b''

    def connect(self):
        self.s.connect(('127.0.0.1', 6666))

    def close(self):
        self.s.close()

    def recv_prepare(self, cnt):
        self.recv_buf = bytearray()
        while len(self.recv_buf) < cnt:
            self.recv_buf.extend(self.s.recv(cnt - len(self.recv_buf)))

        self.recv_buf_i = 0

    def skip_read(self, cnt):
        self.recv_buf_i += cnt

    def next_int(self):
        self.recv_buf_i += 4
        return struct.unpack("i", self.recv_buf[self.recv_buf_i - 4:self.recv_buf_i])[0]

    def next_float(self):
        self.recv_buf_i += 4
        return struct.unpack("f", self.recv_buf[self.recv_buf_i - 4:self.recv_buf_i])[0]

    def write_int(self, i):
        self.send_buf += struct.pack('i', i)

    def write_float(self, f):
        self.send_buf += struct.pack('f', f)

    def flush(self):
        self.s.sendall(self.send_buf)
        self.send_buf = b''

recv'ing from socket sieht in diesem Code optimal aus. Aber jetztnext_int undnext_float wurde der zweite Engpass, sie brauchen etwa 1 ms (3000 CPU-Zyklen) pro Aufruf, nur um zu entpacken. Ist es möglich, sie schneller zu machen, wie in C ++?

Antworten auf die Frage(1)

Ihre Antwort auf die Frage