PHP vs Node.js:真正的評測資料

ourjs發表於2014-06-18

  在網頁程式設計領域,我一直使用ASP.NET或LAMP技術寫程式碼,這成為我生活的絕大部分內容。現在,新的亮點是node.js。它是一個在伺服器端執行javascript的框架,並據說通過使用非同步I/ O,提升了一些效能。

  該理論認為,同步I/O 阻塞模型的工作原理是這樣的:    

   (注* 關於非同步非阻塞模型的工作原理,可參見:  是什麼讓Node.js比Java更快? )

 

  I / O是一個典型的網路事務(web transaction)中的最昂貴的部分。當一個請求到達Apache Web伺服器,它傳遞給PHP直譯器來執行指令碼的動態內容。現在到了棘手的部分 - 如果PHP指令碼想要從磁碟/資料庫讀取或存取資料,這就成了最慢的一環。當你呼叫PHP函式 file_get_contents(),整個執行緒被阻塞,直到內容獲取完成!直到你的指令碼獲得檔案內容,伺服器不能做任何事情。想像一下當併發請求增加數倍時,會發生什麼?他們要排隊,因為沒有可用的執行緒可以做這份工作,因為他們都被I/O阻塞了!

  這裡談到了 node.js 中獨特的賣點緣於 node.js 在幾乎所有的功能中都使用非同步I / O,在上述方案中,只要伺服器執行緒一被釋放,檔案檢索功能(fs.readFile)就被呼叫。然後,一旦在I / O完成後,節點才會執行傳進來的回撥函式(早些時候通過fs.readFile)。在此期間,該有價值的執行緒就可以用於服務其它一些請求。

  所以,這就是關於它的理論。但我不是那種只是因為它被大肆宣傳或者每個人都使用它就接受新風潮的人。不,我想在知道事實真相,並親自來驗證它。我想看看這個理論是否能經得起實際操作的考驗。 

  所以為了測試它,我自己寫了兩個簡單的指令碼 —— 一個在PHP(託管在apache2的),另一個是JavaScript(託管在node.js上的)。測試本身是非常簡單的。該指令碼將:

  1,接受請求。 

  2,生成一個隨機的108千位元組的字串。 

  3,將字串寫到磁碟的檔案上。 

  4,從磁碟中讀取內容。 

  5,在返回的響應流中返回字串。 

  這是第一個指令碼,index.php檔案:

<?php
//index.php
$s=""; //generate a random string of 108KB and a random filename
$fname = chr(rand(0,57)+65).chr(rand(0,57)+65).chr(rand(0,57)+65).chr(rand(0,57)+65).'.txt';
for($i=0;$i<108000;$i++)
{
$n=rand(0,57)+65;
$s = $s.chr($n);
}
 
//write s to a file
file_put_contents($fname,$s);
$result = file_get_contents($fname);
echo $result;

  這是第二個指令碼

//server.js
var http = require('http'); 
var server = http.createServer(handler);
 
function handler(request, response) {
    //console.log('request received!');
    response.writeHead(200, {'Content-Type': 'text/plain'});
 
    s=""; //generate a random string of 108KB and a random filename
    fname = String.fromCharCode(Math.floor(65 + (Math.random()*(122-65)) )) +
        String.fromCharCode(Math.floor(65 + (Math.random()*(122-65)) )) +
        String.fromCharCode(Math.floor(65 + (Math.random()*(122-65)) )) + 
        String.fromCharCode(Math.floor(65 + (Math.random()*(122-65)) )) + ".txt";
 
    for(i=0;i<108000;i++)
    {
        n=Math.floor(65 + (Math.random()*(122-65)) );
        s+=String.fromCharCode(n);
    }
 
    //write s to a file
    var fs = require('fs');
    fs.writeFile(fname, s, function(err, fd) {
            if (err) throw err;
            //console.log("The file was saved!");
            //read back from the file
            fs.readFile(fname, function (err, data) {
                if (err) throw err;
                result = data;
                response.end(result);
            }); 
        }
    );
}
 
server.listen(8124);
console.log('Server running at http://127.0.0.1:8124/');

  然後,然後我通過apache評測工具,向他們兩者一共發了2000個請求(200併發)。當我看到時間統計結果,我大吃一驚: 

#PHP:
Concurrency Level:      200
Time taken for tests:   574.796 seconds
Complete requests:      2000
 
#node.js:
Concurrency Level:      200
Time taken for tests:   41.887 seconds
Complete requests:      2000

  真相大白了。node.js比PHP快14倍!這結果是驚人的。它簡直意味著node.js將在不久的未來成為編寫效能驅動應用程式事實上的標準,這也是毫無疑問的!

  大家一致認為NodeJS生態系統還沒有被廣泛開發掘,並且大多數節點模組,比如資料庫連線,網路接入,公用設施等,正在積極開發中。但儘管如此,看到這些結果後,實在是太顯而易見了。在發展node.js應用程式所花費的任何額外的努力都是非常值得的。 PHP的可能仍然保持著“網頁之王”的狀態,但是作為焦點的node.js,我估計這種狀態不會持續很長時間!

  更新 

  從下面一節看了一些評論之後,我覺得有義務也建立一個C#/mono 版本。不幸的是,這個已經被證明是最慢的一組(約40秒1個請求)。也許是我的程式寫錯了,或者我的程式碼有什麼錯誤。一旦等我閒下來我就會解決它,也許我的下一篇文章就是ASP.NET vs node.js vs PHP!。

  參考文獻:

  1 https://en.wikipedia.org/wiki/Node.js

  2 http://notes.ericjiang.com/posts/751

  3 http://nodejs.org

  4.https://code.google.com/p/node-js-vs-apache-php-benchmark/wiki/Tests

相關文章