Twisted vs Tornado vs Go ����Ʊ��Web�����С��з�
������ takada-at �ε����ǡ֥����С�¦�Ǥ�ñ���100ms�ԤäƤ���쥹�ݥ󥹤��֤������Υڡ������Ѱդ��Ƥ������פȤ��ä��ΤǤ����������Ϥ��Υ����С�¦���ä򤷤ޤ���
��Ȥ�Ȥ��Υ����С����ä�ư���ϡ�takada-at �����������ٻ�����ƥब�������������٤򤫤����뤫�ɤ����򸡾ڤ��뤿��Ǥ����� �����˥쥹�ݥ󥹤��֤��Ƥ��ޤ��ȡ���ٻ������ץȤ���������������٤򤫤����ʤ��Ƥ� PV/sec ���ФƤ��ޤ��ޤ��� �����ǡ� epoll ��Ȥäƹ�®��������³�򰷤���Twisted�ե졼������Ȥäơ�100ms���ٱ�򤷤ĤĿ���PV/sec���Ѥ���Web�����С����äƤߤޤ����� ����ˡ�Ʊ���� epoll ��ȤäƤ��� Tornado �� Go �ˤⶽ̣�����ä��Τǡ�������Ǥ�Ʊ����Τ���������ѥե����ޥ󥹤���Ӥ��Ƥߤޤ�����
������
�ޤ��ϡ������ɤ򸫤Ƥߤޤ��礦��
Twisted Python:
from twisted.internet import epollreactor epollreactor.install() from twisted.web import server, resource from twisted.internet import reactor class Lazy(resource.Resource): isLeaf = True def __init__(self, delay=0.1): self._delay = delay def render_GET(self, request): def after(): request.write('Hello, World!') request.finish() reactor.callLater(self._delay, after) return server.NOT_DONE_YET if __name__ == '__main__': import sys delay = 0.1 try: delay = float(sys.argv[1]) / 1000 except Exception: pass site = server.Site(Lazy(delay)) reactor.listenTCP(8000, site) reactor.run()
���ϡ�Tornado�Ǥ���
from tornado import httpserver, ioloop, web from time import time DELAY = 0.1 class MainHandler(web.RequestHandler): @web.asynchronous def get(self): def _hello(): self.write("Hello, World!") self.finish() ioloop.IOLoop.instance().add_timeout(time() + DELAY, _hello) application = web.Application([ (r"/", MainHandler), ]) if __name__ == "__main__": import sys try: DELAY = float(sys.argv[1]) / 1000 except Exception: pass http_server = httpserver.HTTPServer(application) http_server.listen(8001) ioloop.IOLoop.instance().start()
�Ǹ�ˡ�Go�Ǥ���
package main import ( "flag" "http" "io" "log" "time" ) var addr = flag.String("addr", ":9000", "http service address") var delay = flag.Int64("delay", 100, "response delay[ms]") func main() { flag.Int64Var(delay, "d", 100, "response delay[ms]") flag.Parse() http.Handle("/", http.HandlerFunc(hello)) err := http.ListenAndServe(*addr, nil) if err != nil { log.Exit("ListenAndServe:", err) } } func hello(c *http.Conn, req *http.Request) { time.Sleep(int64(1000000) * int64(*delay)) io.WriteString(c, "Hello, World!\n") }
Twisted��Tornado�ϡ��롼�פ˸�ǸƤӽФ��ؿ�����Ͽ���Ƥ��Ƥ������餫�˥��٥�ȥɥ�֥�ե졼�����Ȥ������������ޤ��� ������Ф���Go�� Sleep() ��ȤäƤ��ơ��츫���̤Υ���åɤ١�������������˸����ޤ��� ��������Go�ϥͥ��ƥ��֥���åɤǤϤʤ�goroutine�Ȥ������̤ʥ桼�������ɥ���åɤ����Ѥ��Ƥ��ꡢ���Υ������塼��ϡ�Linux�ξ���epoll�����Ѥ��Ƥ��ޤ����̾�Υ���åɤ�Ȥ������ΨŪ��ư���Ϥ��Ǥ���
�٥���ޡ���
����Ǥϡ�����3�Ĥˤ��줾����٤򤫤��Ƥߤޤ��礦���Ȥ��äƤ⡢100ms���ٱ������٤򤫤���Τ����ѤʤΤǡ�10ms���ٱ�Ǽ¹Ԥ���ab -c100 -n10000�Ǽ¸����Ƥߤޤ���
Twisted: Requests per second: 2620.31 [#/sec] (mean) Time per request: 38.163 [ms] (mean) Time per request: 0.382 [ms] (mean, across all concurrent requests) Percentage of the requests served within a certain time (ms) 50% 31 66% 32 75% 33 80% 37 90% 38 95% 38 98% 40 99% 44 100% 3082 (longest request) Tornado: Requests per second: 5299.04 [#/sec] (mean) Time per request: 18.871 [ms] (mean) Time per request: 0.189 [ms] (mean, across all concurrent requests) Percentage of the requests served within a certain time (ms) 50% 19 66% 19 75% 19 80% 19 90% 19 95% 19 98% 21 99% 22 100% 33 (longest request) Go: Requests per second: 4712.63 [#/sec] (mean) Time per request: 21.220 [ms] (mean) Time per request: 0.212 [ms] (mean, across all concurrent requests) Percentage of the requests served within a certain time (ms) 50% 19 66% 20 75% 20 80% 21 90% 32 95% 40 98% 42 99% 42 100% 48 (longest request)
Tornado��Go����٤�ȡ�Twisted����ǰ�ʷ�̤ˤʤäƤ��ޤ��� ����ϡ�Twisted�����Ū����Ū�ǹⵡǽ�ʥե졼�����Ȥ������Ȥ⤢��ޤ������ٱ�¹Ԥ���ؿ���ꥹ�Ȥ˳�Ǽ���Ƥ��ơ��¹Ԥ���ؿ������뤫�ɤ�����ꥹ�Ȥ����������å����Ƥ���Τ��ç¤ï¿½ï¿½ï¿½ï¿½ï¿½Ç¤ï¿½ï¿½ï¿½ï¿½ï¿½Tornado�ϥ����ȺѤߥꥹ�Ȥ����Ѥ��Ƥ��Ƥޤ���
Go�⡢����ѥ��鷿�ʤΤ�Tornado���餱�Ƥ�Τ���ǰ�Ǥ�����epoll����ľ�ܥ��٥�ȥɥ�֥󤷤Ƥ���Tornado����٤�� goroutine �Ȥ�����ݲ��쥤���1��Ϥ���Ǥ���Τǻ����ʤ����⤷��ޤ���
����˹�®��
�ޤ���Tornado��JIT�ˤ���®����ĩ�路�Ƥߤޤ���PyPy-1.2�����֤褵�����Ǥ��������åȥ��åפ����ݤʤΤǤ���ڤ�psyco��ȤäƤߤޤ�������ȤΥ����������ɤˡ�����2�Ԥ��ɲä��ޤ���
import psyco psyco.full()
��̤Ϥ����ʤ�ޤ�����
Requests per second: 7503.16 [#/sec] (mean) Time per request: 13.328 [ms] (mean) Time per request: 0.133 [ms] (mean, across all concurrent requests) Percentage of the requests served within a certain time (ms) 50% 13 66% 13 75% 14 80% 14 90% 14 95% 14 98% 15 99% 15 100% 23 (longest request)
5299req/sec => 7503req/sec �ǡ�20��ʾ��®���Ǥ��ޤ�����top�Ǹ��Ƥ���¤ꡢ���������(RES)��1MB�ʲ��Ǥ���Tornado+psyco������ͥ���Ǥ��͡�
���ˡ�Go�ǥޥ������åɲ����Ƥߤޤ���goroutine��ʣ���Υͥ��ƥ��֥���åɤ����Ѥ��������ư��뤳�Ȥ��Ǥ��ޤ������������������ǤϤޤ��������塼�餬�褯�ʤ��餷�����ǥե���ȤǤϥޥ������åɤ�Ȥ�ʤ��褦�ˤʤäƤ��ޤ����Ķ��ѿ� GOMAXPROCS �����������ꤷ�Ƽ¸����Ƥߤޤ�����
GOMAXPROCS=6 ��: Requests per second: 5760.33 [#/sec] (mean) Time per request: 17.360 [ms] (mean) Time per request: 0.174 [ms] (mean, across all concurrent requests) Percentage of the requests served within a certain time (ms) 50% 16 66% 17 75% 17 80% 18 90% 28 95% 33 98% 37 99% 40 100% 53 (longest request)
�¸��ޥ����Core2 Duo��2���������ܤäƤ��ʤ�(Hyper Threading��ʤ�)�ʤΤǤ�����2����ꤷ�Ƥ⤢�ޤ���ǽ���夬�餺����������1�Ĥ��Ŀ�����夲�Ƥ��ä��Ȥ���6�ޤǤϾ���������ǽ�����夷�Ƥ����ޤ����������⡢top�򸫤Ƥ���¤�CPU����Ψ�Ϻ����200%�ˤ������Ϥ���120%�ʲ��������ѤǤ��Ƥ��ޤ��� CPU�򸶰���Ƚ��ޤ��󤬡�����Τ褦�ʥ��٥�ȥ롼�פ�إӡ��˻Ȥ����Ӥˤϥ������塼�餬��Ŭ������Ƥ��餺����äȥ����С�¦��CPU�����Ѥ���׻���Ԥ������򤷤ʤ��ȥޥ��������Ȥ�����ʤ��Τ��⤷��ޤ���
Go�Ϻ���Υ������Ǥ�Tornado���餱�Ƥ��ޤ��ޤ�������IO¿�Ų��򥤥٥�ȥɥ�֥��ꥷ��ץ�˵��ҤǤ�������ѥ��뷿����ʤΤ�ʣ���ʷ׻���Python��갵��Ū�˹�®�˷׻��Ǥ������ʤΤǡ����˴��Ԥ��Ƥ��ޤ���