C10K問題的解決,涌現出一大批新框架,或者新語言,那麼問題來了:到底誰最快呢?非專業程序猿來個非專業對比。html
比較程序:輸出Hello World!node
測試程序:siege –c 100 –r 100 –bpython
例子包括:git
1.go用http模塊實現的helloworldgithub
2.go用martini微框架實現的Helloworldgolang
3.python3 python2 pypy分別用gevent server tornado實現的Hello worldweb
4.python3 python2 pypy分別用微框架bottle+gevent實現的Hello worldexpress
5.NodeJS純JS實現的Helloworld服務器
6.NodeJS用express框架實現的Helloworldapp
測試平臺:
公司老舊的奔騰平臺 Pentium(R) Dual-Core CPU E6700 @ 3.20GHz
內存2GB(夠弱了吧)
先來宇宙最快的GO的測試:
1 package main 2 3 import ( 4 "fmt" 5 "net/http" 6 ) 7 8 func sayhelloName(w http.ResponseWriter, r *http.Request){ 9 fmt.Fprintf(w, "hello world!") 10 } 11 12 func main() { 13 http.HandleFunc("/", sayhelloName) 14 http.ListenAndServe(":9090", nil) 15 }
連續測試5次,成績大致以下:
1 Transactions: 10000 hits 2 Availability: 100.00 % 3 Elapsed time: 4.11 secs 4 Data transferred: 0.11 MB 5 Response time: 0.03 secs 6 Transaction rate: 2433.09 trans/sec 7 Throughput: 0.03 MB/sec 8 Concurrency: 79.76 9 Successful transactions: 10000 10 Failed transactions: 0 11 Longest transaction: 0.20 12 Shortest transaction: 0.00
4.11秒,不錯的成績
再看NodeJS的例子:
1 var http = require("http"); 2 http.createServer(function(request, response) { 3 response.writeHead(200, {"Content-Type": "text/plain"}); 4 response.write("Hello World!"); 5 response.end(); 6 }).listen(8000); 7 console.log("nodejs start listen 8888 port!"); 8
測試結果以下:
1 Transactions: 10000 hits 2 Availability: 100.00 % 3 Elapsed time: 5.00 secs 4 Data transferred: 0.11 MB 5 Response time: 0.04 secs 6 Transaction rate: 2000.00 trans/sec 7 Throughput: 0.02 MB/sec 8 Concurrency: 86.84 9 Successful transactions: 10000 10 Failed transactions: 0 11 Longest transaction: 0.17 12 Shortest transaction: 0.00
5秒,比Go稍微慢一點
接下來是Python,因爲python自帶的wsgiref服務器,只是一個參考實現,性能不好,因此這裏選用了兩個性能不錯的WSGI服務器gevent、tornado
gevent代碼以下:
1 #!/usr/bin/python 2 from gevent import pywsgi 3 4 def hello_world(env, start_response): 5 if env['PATH_INFO'] == '/': 6 start_response('200 OK', [('Content-Type', 'text/html')]) 7 return ["hello world"] 8 9 print 'Serving on https://127.0.0.1:8000' 10 server = pywsgi.WSGIServer(('0.0.0.0', 8000), hello_world ) 11 server.serve_forever() 12
tornado的代碼以下:
1 from tornado import httpserver 2 from tornado import ioloop 3 def handle_request(request): 4 if request.uri=='/': 5 message = b"Hello World!" 6 request.write(b"HTTP/1.1 200 OK\r\nContent-Length: %d\r\n\r\n%s" % ( 7 len(message), message)) 8 request.finish() 9 10 http_server = httpserver.HTTPServer(handle_request) 11 http_server.bind(8888) 12 http_server.start() 13 ioloop.IOLoop.instance().start() 14
因爲python的例子要分別在python2 python3 pypy下跑,結果太多,我這裏只給結果:
gevent:
python2:5.8秒,python3:7.5秒,pypy:4.8秒
有意思的是:pypy第一次跑用了6.8秒,第二次之後全是4.8秒(感受緣由是第一次因爲jit浪費了一點時間)貼出某次pypy的成績:
1 Transactions: 10000 hits 2 Availability: 100.00 % 3 Elapsed time: 4.77 secs 4 Data transferred: 0.10 MB 5 Response time: 0.04 secs 6 Transaction rate: 2096.44 trans/sec 7 Throughput: 0.02 MB/sec 8 Concurrency: 90.38 9 Successful transactions: 10000 10 Failed transactions: 0 11 Longest transaction: 0.13 12 Shortest transaction: 0.00 13
接下來是tornado:
python2:9.05秒,python3:8.6秒,pypy:5.95秒
一樣:pypy第一次執行的時間爲9.45秒,之後的每次只執行時間爲5.9秒多一些
能夠看出,pypy 與go nodejs性能至關,其中go最快爲4.11秒,pypy+gevent與nodejs性能差很少,pypy稍好一點,pypy+tornado則稍慢於nodejs。
2。框架篇:
從上邊例子能夠看到,純代碼寫起來仍是比較麻煩的,通常咱們都是用框架來寫web,我選了幾個輕量級的框架來輸出helloworld:
go+martini
1 package main 2 3 import "github.com/codegangsta/martini" 4 5 func main() { 6 m := martini.Classic() 7 m.Get("/", func() string { 8 return "Hello world!" 9 }) 10 m.Run() 11 } 12
運行時間爲:
1 Transactions: 10000 hits 2 Availability: 100.00 % 3 Elapsed time: 4.69 secs 4 Data transferred: 0.11 MB 5 Response time: 0.04 secs 6 Transaction rate: 2132.20 trans/sec 7 Throughput: 0.02 MB/sec 8 Concurrency: 90.23 9 Successful transactions: 10000 10 Failed transactions: 0 11 Longest transaction: 0.17 12 Shortest transaction: 0.00 13
nodejs+express:
1 var express = require('express') 2 var app = express() 3 4 app.get('/', function (req, res) { 5 res.send('Hello World') 6 }) 7 8 app.listen(3000)
用時:
1 Transactions: 10000 hits 2 Availability: 100.00 % 3 Elapsed time: 5.90 secs 4 Data transferred: 0.10 MB 5 Response time: 0.06 secs 6 Transaction rate: 1694.92 trans/sec 7 Throughput: 0.02 MB/sec 8 Concurrency: 96.44 9 Successful transactions: 10000 10 Failed transactions: 0 11 Longest transaction: 0.13 12 Shortest transaction: 0.01 13
python gevent+bottle:
1 from gevent import monkey 2 monkey.patch_all() 3 from bottle import run,get 4 5 @get("/") 6 def index(): 7 return "Hello world!" 8 9 run(server='gevent') 10
用時:python2 10.05秒,python3:12.95秒,pypy:5.85秒
python tornado:
1 import tornado.httpserver 2 import tornado.ioloop 3 import tornado.web 4 5 class IndexHandler(tornado.web.RequestHandler): 6 def get(self): 7 self.write('Hello World!') 8 9 if __name__ == "__main__": 10 app = tornado.web.Application(handlers=[(r"/",IndexHandler)]) 11 http_server = tornado.httpserver.HTTPServer(app) 12 http_server.listen(8000) 13 tornado.ioloop.IOLoop.instance().start() 14
用時:python2 11.85秒,python3:11.79秒,pypy:6.65秒
總結:能夠看到,python在開啓jit技術的pypy上web響應速度已經略優於nodejs,跟golang還有必定差距,但在同一數量級,標準python就稍微慢一些。