1. 程式人生 > >web程式設計速度大比拼(nodejs go python)(非專業對比)

web程式設計速度大比拼(nodejs go python)(非專業對比)

C10K問題的解決,湧現出一大批新框架,或者新語言,那麼問題來了:到底誰最快呢?非專業程式猿來個非專業對比。

比較程式:輸出Hello World!

測試程式:siege –c 100 –r 100 –b

例子包括:

1.go用http模組實現的helloworld

2.go用martini微框架實現的Helloworld

3.python3 python2 pypy分別用gevent server  tornado實現的Hello world

4.python3 python2 pypy分別用微框架bottle+gevent實現的Hello world

5.NodeJS純JS實現的Helloworld

6.NodeJS用express框架實現的Helloworld

測試平臺:

公司老舊的奔騰平臺 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就稍微慢一些。