recv () działa zbyt wolno
Cześć, jestem całkiem początkującym w Pythonie. Piszę prostą grę w sieci LAN (nie jest to dla mnie proste) za pomocą modułu pygame.
Oto problem - mam dwa komputery (jeden stary netbook intel Atom, drugi intel i5 NTB). Chcę osiągnąć co najmniej 5 FPS (netbook spowalnia NTB, ale nie aż tak bardzo, teraz mam około 1,5 FPS), ale wywołanie funkcji recv () dwukrotnie w pętli głównej zajmuje łącznie około 0,5 sekundy na każdej maszyna. Sygnał Wi-Fi jest silny, a router ma przepustowość 300 Mb / s i wysyła krótki ciąg o długości około 500 znaków. Jak widać przy pomiarze czasu używam time.clock ().
Oto część kodu „serwera”, który zwykle uruchamiam na NTB i5:
while 1:
start = time.clock()
messagelen = c.recv(4) #length of the following message (fixed 4 character)
if " " in messagelen:
messagelen = messagelen.replace(" ","")
message = cPickle.loads(c.recv(int(messagelen))) #list of the arrows, other player position and changes in the game map
arrowsmod = message[0]
modtankposan = message[1]
removelistmod = message[2]
for i in removelistmod:
try:
randopos.remove(i)
except ValueError:
randopossv.remove(i)
print time.clock()-start
tosendlist=[]
if len(arrows) == 0: #if there are no arrows it appends only an empty list
tosendlist.append([])
else:
tosendlist.append(arrows)
tosendlist.append([zeltankpos, 360-angle])
if len(removelist) == 0: #if there are no changes of the map it appends only an empty list
tosendlist.append([])
else:
tosendlist.append(removelist)
removelist=[]
tosend=cPickle.dumps(tosendlist)
tosendlen = str(len(tosend))
while len(tosendlen)<4:
tosendlen+=" "
c.sendall(tosendlen) #sends the length to client
c.sendall(tosend) #sends the actual message(dumped list of lists) to client
...something else which takes <0,05 sec on the NTB
Oto część kodu „klienta” (tylko odwrócił początek - wysyłanie / odbieranie części):
while 1:
tosendlist=[]
if len(arrows) == 0: #if there are no arrows it appends only an empty list
tosendlist.append([])
else:
tosendlist.append(arrows)
tosendlist.append([zeltankpos, 360-angle])
if len(removelist) == 0: #if there are no changes of the map it appends only an empty list
tosendlist.append([])
else:
tosendlist.append(removelist)
removelist=[]
tosend=cPickle.dumps(tosendlist)
tosendlen = str(len(tosend))
while len(tosendlen)<4:
tosendlen+=" "
s.sendall(tosendlen) #sends the length to server
s.sendall(tosend) #sends the actual message(dumped list of lists) to server
start = time.clock()
messagelen = s.recv(4) #length of the following message (fixed 4 character)
if " " in messagelen:
messagelen = messagelen.replace(" ","")
message = cPickle.loads(s.recv(int(messagelen))) #list of the arrows, other player position and changes in the game map
arrowsmod = message[0]
modtankposan = message[1]
removelistmod = message[2]
for i in removelistmod:
try:
randopos.remove(i)
except ValueError:
randopossv.remove(i)
print time.clock()-start
... rest which takes on the old netbook <0,17 sec
Kiedy uruchamiam, powiedzmy, wersję gry dla jednego gracza na jednym komputerze (bez modułu gniazda) w iB NTB ma on 50 FPS w lewym górnym rogu mapy i 25 FPS w prawym dolnym rogu (mapa 1000x1000 pikseli zawiera kwadraty 5x5 pikseli, myślę, że jest wolniejszy z powodu większych współrzędnych, ale nie mogę w to tak bardzo uwierzyć. BTW recv podczas biegu, ponieważ gra LAN w prawym dolnym rogu mapy zajmuje około tego samego czasu) Netbook Atom ma 4-8 FPS.
Czy mógłbyś mi powiedzieć, dlaczego jest tak powolny? Komputery nie są zsynchronizowane, jeden jest szybszy, drugi wolniejszy, ale nie może być tak, że czekają na siebie, byłoby to maksymalnie 0,17 s opóźnienia, prawda? Oraz długie wywołanie recv byłoby tylko na szybszym komputerze? Nie wiem też dokładnie, jak działa funkcja wysyłania / odzyskiwania. To dziwne, że sendall nie zabiera dosłownie czasu, gdy odbieranie zajmuje 0,5 sekundy. Może sendall próbuje wysłać w tle, podczas gdy reszta programu jest kontynuowana.