您的位置:首页 > Web前端 > Node.js

C#、PHP与NodeJs性能测试对比

2014-06-15 09:40 671 查看
http://www.prahladyeri.com/2014/06/php-vs-node-js-real-statistics/

在网络编程领域,常用的解决方案就是JSP(SSH)、ASP.NET、PHP加上LAMP这种架构。不过,现在这个大家庭加入了NodeJS,这个轻量级的基于JavaScript服务端库的平台可以使用异步I/O的方式来提升整体的性能。



I/O操作是网络传输中占用资源最大的模块。当Apache服务器接收到请求时,它会将它传输到PHP解释器来执行任何动态脚本的模块。这也是最棘手的模块,如果PHP脚本需要从磁盘或者数据库中读写数据,这回成为整个环节中最慢的一环。如果调用PHP中的file_get_contents()函数,整个线程都会被阻塞直到文件内容被获取到。在此期间服务器不能进行任何操作。如果大量用户同时发出此类请求,那么这些请求都会进入一个等待队列,因为所有的线程都被阻塞了。

而非阻塞操作也是NodeJs最大的特点之一。鉴于NodeJs在它所有的函数中都进行了异步操作,上述场景中的情况在NodeJs中反应就大相径庭。一旦文件调用了fs.readFile函数,该线程会被立刻释放。而当I/O操作结束之后,会自动回调某个在readFile中指定的函数对传入的数据参数进行操作。同时,该线程可以用于处理其他请求。

虽然从原理上可以看出这种机制能够有效地降低用户等待时间,但是还是需要用数据来说明一切。

1.接受请求。

2. 随机生成108千字节的字符串。

3. 将字符串写入到磁盘文件中。

4. 从磁盘文件中读取内容。

5. 将字符串输出到响应流中。

PHP代码 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;

NodeJs代码 server.js:

//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/s),结果还是挺惊人的:

#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

事实证明NodeJs比PHP大概快上了14倍,结果是非常令人惊讶的,NodeJs杠杠的未来的Web趋势啊。尽管目前NodeJs的生态系统并未十分完善,大部分的面向数据库连接、网络接入、工具等等的模块也是尚未开发完毕,但是根据以上结果,窃以为PHP不会在Web之王的宝座上待太久了。

更新

我也对C#/mono版本进行了测试,结果非常差,大概每个请求的响应时间为40秒,可能是mono的任务库出现了问题,或者我的代码的哪里出错了吧。

namespace Benchmark

{

using System;

using System.Web;

using System.Web.UI;

using System.Threading.Tasks;

public partial class Default : System.Web.UI.Page

{

Random rnd=null;

public void Page_Load(object sender, EventArgs e)

{

//RegisterAsyncTask(new PageAsyncTask(PerformIOasync,PerformIOasync,null,null));

rnd = new Random ();

//Task.Run (new Action (PerformIOasync));

PerformIOasync ();

}

public async void PerformIOasync()

{

string s=""; //generate a random string of 108KB and a random filename

string fname = rndchar() + rndchar() + rndchar() + rndchar() +".txt";

for(int i=0;i<108000;i++)

{

char ch=rndchar();

s += ch;

}

//write s to a file

//file_put_contents($fname,$s);

var slowTask1 = Task<string>.Factory.StartNew(()=> WriteToDisk(fname,s));

await slowTask1;

var SlowTask2 = Task<string>.Factory.StartNew(()=> ReadFromDisk(fname,s));

await SlowTask2;

Response.Write(SlowTask2.Result.ToString());

}

private string WriteToDisk(string fname, string s){

System.IO.File.WriteAllText (AppDomain.CurrentDomain.BaseDirectory + fname, s);

return "";

}

private string ReadFromDisk(string fname, string s){

return System.IO.File.ReadAllText (AppDomain.CurrentDomain.BaseDirectory + fname);

}

private char rndchar()

{

return (char)rnd.Next (65, 112);

}

}

}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: