A simple TCP echo server using epoll reactor:this server process take 60% cpu on 4000 request/s.
If use self.transport.getHandle().send instead of self.transport.write,it take 30% cpu on 4000 request/s.
Why transport.write take more user cpu?Why twisted performance so poor?(echosvr.c using libevent only take 12% cpu on 4000 request/s)
tsvr.py-----------------------------------------------------------import sys, time, random, socket, tracebackfrom twisted.internet import epollreactorepollreactor.install()from twisted.internet import defer, reactor, taskfrom twisted.internet.protocol import Protocol, Factoryfrom protocol import TCPServerProtocol
def main(): tcpprotocol = TCPServerProtocol factory = Factory() factory.protocol = tcpprotocol reactor.listenTCP(9976, factory) reactor.run()
if __name__ == '__main__': main()
protocol.py--------------------------------------------------------- import socketimport datetimeimport tracebackfrom twisted.protocols.basic import LineReceiverfrom twisted.internet import protocol
class TCPServerProtocol(LineReceiver): req_count = 0 req_time = datetime.datetime.now()
def lineReceived(self, data): TCPServerProtocol.req_count+=1 if TCPServerProtocol.req_count%10000==0: ct = datetime.datetime.now() dt = ct-TCPServerProtocol.req_time pps = 10000/(dt.seconds+dt.microseconds/1000000.0) TCPServerProtocol.req_time=ct print('RPS='+str(pps)) try: #self.transport.write(data) self.transport.getHandle().send(data) except: traceback.print_exc()
tcli.py -----------------------------------------------------------------import sysimport socketimport tracebackimport timeimport datetime
host = 'localhost'port = 9976loopcount = 300sockcount = 5000RPS = 4000
ss=[]for x in xrange(sockcount): ss.append(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) ss[x].connect((host, port)) ss[x].settimeout(120)
for x in xrange(10000000): st = datetime.datetime.now() for y in xrange(loopcount): try: if ss[x%sockcount]!=None: ss[x%sockcount].sendall('1234567890\r\n') ss[x%sockcount].recv(1024) except: print y sys.exit() time.sleep(0.1) dt = (datetime.datetime.now()-st) plc = loopcount/(dt.seconds+dt.microseconds/1000000.0) print loopcount/(dt.seconds+dt.microseconds/1000000.0) #auto adjust RPS if plc