Jump to content
Nytro

PHP vs node.js: The REAL statistics

Recommended Posts

PHP vs node.js: The REAL statistics

10 June, 2014 Prahlad Yeri

When it comes to web programming, I’ve always coded in ASP.NET or the LAMP technologies for most part of my life. Now, the new buzz in the city is node.js. It is a light-weight platform that runs javascript code on server-side and is said to improvise performance by using async I/O.

The theory suggests that synchronous or blocking model of I/O works something like this:

nodejs.png

I/O is typically the costliest part of a web transaction. When a request arrives to the apache web server, it passes it to PHP interpreter for scripting any dynamic contents. Now comes the tricky part – If the PHP script wants to read something from the disk/database or write to it, that is the slowest link in the chain. When you call PHP function file_get_contents(), the entire thread is blocked until the contents are retrieved! The server can’t do anything until your script gets the file contents. Consider what happens when multiples of simultaneous requests are issued by different users to your server? They get queued, because no thread is available to do the job since they are all blocked in I/O!

Here comes the unique selling-point of node.js. Since node.js implements async I/O in almost all its functions, the server thread in the above scenario is freed as soon as the file retrieval function (fs.readFile) is called. Then, once the I/O completes, node calls a function (passed earlier by fs.readFile) along with the data parameters. In the meantime, that valuable thread can be used for serving some other request.

So thats the theory about it anyway. But I’m not someone who just accepts any new fad in the town just because it is hype and everyone uses it. Nope, I want to get under the covers and verify it for myself. I wanted to see whether this theory holds in actual practice or not.

So I brought upon myself the job of writing two simple scripts for benchmarking this – one in PHP (hosted on apache2) and other in javascript (hosted on node.js). The test itself was very simple. The script would:

1. Accept the request.

2. Generate a random string of 108 kilobytes.

3. Write the string to a file on the disk.

4. Read the contents back from disk.

5. Return the string back on the response stream.

This is the first script, index.php:

[COLOR=#000000][B]<?php[/B][/COLOR]
[COLOR=#666666][I]//index.php[/I][/COLOR]
[COLOR=#000088]$s[/COLOR][COLOR=#339933]=[/COLOR][COLOR=#0000ff]""[/COLOR][COLOR=#339933];[/COLOR] [COLOR=#666666][I]//generate a random string of 108KB and a random filename[/I][/COLOR]
[COLOR=#000088]$fname[/COLOR] [COLOR=#339933]=[/COLOR] [COLOR=#990000]chr[/COLOR][COLOR=#009900]([/COLOR][COLOR=#990000]rand[/COLOR][COLOR=#009900]([/COLOR][COLOR=#cc66cc]0[/COLOR][COLOR=#339933],[/COLOR][COLOR=#cc66cc]57[/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933]+[/COLOR][COLOR=#cc66cc]65[/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933].[/COLOR][COLOR=#990000]chr[/COLOR][COLOR=#009900]([/COLOR][COLOR=#990000]rand[/COLOR][COLOR=#009900]([/COLOR][COLOR=#cc66cc]0[/COLOR][COLOR=#339933],[/COLOR][COLOR=#cc66cc]57[/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933]+[/COLOR][COLOR=#cc66cc]65[/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933].[/COLOR][COLOR=#990000]chr[/COLOR][COLOR=#009900]([/COLOR][COLOR=#990000]rand[/COLOR][COLOR=#009900]([/COLOR][COLOR=#cc66cc]0[/COLOR][COLOR=#339933],[/COLOR][COLOR=#cc66cc]57[/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933]+[/COLOR][COLOR=#cc66cc]65[/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933].[/COLOR][COLOR=#990000]chr[/COLOR][COLOR=#009900]([/COLOR][COLOR=#990000]rand[/COLOR][COLOR=#009900]([/COLOR][COLOR=#cc66cc]0[/COLOR][COLOR=#339933],[/COLOR][COLOR=#cc66cc]57[/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933]+[/COLOR][COLOR=#cc66cc]65[/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933].[/COLOR][COLOR=#0000ff]'.txt'[/COLOR][COLOR=#339933];[/COLOR]
[COLOR=#b1b100]for[/COLOR][COLOR=#009900]([/COLOR][COLOR=#000088]$i[/COLOR][COLOR=#339933]=[/COLOR][COLOR=#cc66cc]0[/COLOR][COLOR=#339933];[/COLOR][COLOR=#000088]$i[/COLOR][COLOR=#339933]<[/COLOR][COLOR=#cc66cc]108000[/COLOR][COLOR=#339933];[/COLOR][COLOR=#000088]$i[/COLOR][COLOR=#339933]++[/COLOR][COLOR=#009900])[/COLOR]
[COLOR=#009900]{[/COLOR]
[COLOR=#000088]$n[/COLOR][COLOR=#339933]=[/COLOR][COLOR=#990000]rand[/COLOR][COLOR=#009900]([/COLOR][COLOR=#cc66cc]0[/COLOR][COLOR=#339933],[/COLOR][COLOR=#cc66cc]57[/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933]+[/COLOR][COLOR=#cc66cc]65[/COLOR][COLOR=#339933];[/COLOR]
[COLOR=#000088]$s[/COLOR] [COLOR=#339933]=[/COLOR] [COLOR=#000088]$s[/COLOR][COLOR=#339933].[/COLOR][COLOR=#990000]chr[/COLOR][COLOR=#009900]([/COLOR][COLOR=#000088]$n[/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR]
[COLOR=#009900]}[/COLOR]

[COLOR=#666666][I]//write s to a file[/I][/COLOR]
[COLOR=#990000]file_put_contents[/COLOR][COLOR=#009900]([/COLOR][COLOR=#000088]$fname[/COLOR][COLOR=#339933],[/COLOR][COLOR=#000088]$s[/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR]
[COLOR=#000088]$result[/COLOR] [COLOR=#339933]=[/COLOR] [COLOR=#990000]file_get_contents[/COLOR][COLOR=#009900]([/COLOR][COLOR=#000088]$fname[/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR]
[COLOR=#b1b100]echo[/COLOR] [COLOR=#000088]$result[/COLOR][COLOR=#339933];[/COLOR]

And here is the second script, server.js:

[COLOR=#006600][I]//server.js[/I][/COLOR]
[COLOR=#000066][B]var[/B][/COLOR] http [COLOR=#339933]=[/COLOR] require[COLOR=#009900]([/COLOR][COLOR=#3366CC]'http'[/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR]
[COLOR=#000066][B]var[/B][/COLOR] server [COLOR=#339933]=[/COLOR] http.[COLOR=#660066]createServer[/COLOR][COLOR=#009900]([/COLOR]handler[COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR]

[COLOR=#000066][B]function[/B][/COLOR] handler[COLOR=#009900]([/COLOR]request[COLOR=#339933],[/COLOR] response[COLOR=#009900])[/COLOR] [COLOR=#009900]{[/COLOR]
[COLOR=#006600][I]//console.log('request received!');[/I][/COLOR]
response.[COLOR=#660066]writeHead[/COLOR][COLOR=#009900]([/COLOR][COLOR=#CC0000]200[/COLOR][COLOR=#339933],[/COLOR] [COLOR=#009900]{[/COLOR][COLOR=#3366CC]'Content-Type'[/COLOR][COLOR=#339933]:[/COLOR] [COLOR=#3366CC]'text/plain'[/COLOR][COLOR=#009900]}[/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR]

s[COLOR=#339933]=[/COLOR][COLOR=#3366CC]""[/COLOR][COLOR=#339933];[/COLOR] [COLOR=#006600][I]//generate a random string of 108KB and a random filename[/I][/COLOR]
fname [COLOR=#339933]=[/COLOR] String.[COLOR=#660066]fromCharCode[/COLOR][COLOR=#009900]([/COLOR]Math.[COLOR=#660066]floor[/COLOR][COLOR=#009900]([/COLOR][COLOR=#CC0000]65[/COLOR] [COLOR=#339933]+[/COLOR] [COLOR=#009900]([/COLOR]Math.[COLOR=#660066]random[/COLOR][COLOR=#009900]([/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933]*[/COLOR][COLOR=#009900]([/COLOR][COLOR=#CC0000]122[/COLOR][COLOR=#339933]-[/COLOR][COLOR=#CC0000]65[/COLOR][COLOR=#009900])[/COLOR][COLOR=#009900])[/COLOR] [COLOR=#009900])[/COLOR][COLOR=#009900])[/COLOR] [COLOR=#339933]+[/COLOR]
String.[COLOR=#660066]fromCharCode[/COLOR][COLOR=#009900]([/COLOR]Math.[COLOR=#660066]floor[/COLOR][COLOR=#009900]([/COLOR][COLOR=#CC0000]65[/COLOR] [COLOR=#339933]+[/COLOR] [COLOR=#009900]([/COLOR]Math.[COLOR=#660066]random[/COLOR][COLOR=#009900]([/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933]*[/COLOR][COLOR=#009900]([/COLOR][COLOR=#CC0000]122[/COLOR][COLOR=#339933]-[/COLOR][COLOR=#CC0000]65[/COLOR][COLOR=#009900])[/COLOR][COLOR=#009900])[/COLOR] [COLOR=#009900])[/COLOR][COLOR=#009900])[/COLOR] [COLOR=#339933]+[/COLOR]
String.[COLOR=#660066]fromCharCode[/COLOR][COLOR=#009900]([/COLOR]Math.[COLOR=#660066]floor[/COLOR][COLOR=#009900]([/COLOR][COLOR=#CC0000]65[/COLOR] [COLOR=#339933]+[/COLOR] [COLOR=#009900]([/COLOR]Math.[COLOR=#660066]random[/COLOR][COLOR=#009900]([/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933]*[/COLOR][COLOR=#009900]([/COLOR][COLOR=#CC0000]122[/COLOR][COLOR=#339933]-[/COLOR][COLOR=#CC0000]65[/COLOR][COLOR=#009900])[/COLOR][COLOR=#009900])[/COLOR] [COLOR=#009900])[/COLOR][COLOR=#009900])[/COLOR] [COLOR=#339933]+[/COLOR]
String.[COLOR=#660066]fromCharCode[/COLOR][COLOR=#009900]([/COLOR]Math.[COLOR=#660066]floor[/COLOR][COLOR=#009900]([/COLOR][COLOR=#CC0000]65[/COLOR] [COLOR=#339933]+[/COLOR] [COLOR=#009900]([/COLOR]Math.[COLOR=#660066]random[/COLOR][COLOR=#009900]([/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933]*[/COLOR][COLOR=#009900]([/COLOR][COLOR=#CC0000]122[/COLOR][COLOR=#339933]-[/COLOR][COLOR=#CC0000]65[/COLOR][COLOR=#009900])[/COLOR][COLOR=#009900])[/COLOR] [COLOR=#009900])[/COLOR][COLOR=#009900])[/COLOR] [COLOR=#339933]+[/COLOR] [COLOR=#3366CC]".txt"[/COLOR][COLOR=#339933];[/COLOR]

[COLOR=#000066][B]for[/B][/COLOR][COLOR=#009900]([/COLOR]i[COLOR=#339933]=[/COLOR][COLOR=#CC0000]0[/COLOR][COLOR=#339933];[/COLOR]i[COLOR=#339933]<[/COLOR][COLOR=#CC0000]108000[/COLOR][COLOR=#339933];[/COLOR]i[COLOR=#339933]++[/COLOR][COLOR=#009900])[/COLOR]
[COLOR=#009900]{[/COLOR]
n[COLOR=#339933]=[/COLOR]Math.[COLOR=#660066]floor[/COLOR][COLOR=#009900]([/COLOR][COLOR=#CC0000]65[/COLOR] [COLOR=#339933]+[/COLOR] [COLOR=#009900]([/COLOR]Math.[COLOR=#660066]random[/COLOR][COLOR=#009900]([/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933]*[/COLOR][COLOR=#009900]([/COLOR][COLOR=#CC0000]122[/COLOR][COLOR=#339933]-[/COLOR][COLOR=#CC0000]65[/COLOR][COLOR=#009900])[/COLOR][COLOR=#009900])[/COLOR] [COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR]
s[COLOR=#339933]+=[/COLOR]String.[COLOR=#660066]fromCharCode[/COLOR][COLOR=#009900]([/COLOR]n[COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR]
[COLOR=#009900]}[/COLOR]

[COLOR=#006600][I]//write s to a file[/I][/COLOR]
[COLOR=#000066][B]var[/B][/COLOR] fs [COLOR=#339933]=[/COLOR] require[COLOR=#009900]([/COLOR][COLOR=#3366CC]'fs'[/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR]
fs.[COLOR=#660066]writeFile[/COLOR][COLOR=#009900]([/COLOR]fname[COLOR=#339933],[/COLOR] s[COLOR=#339933],[/COLOR] [COLOR=#000066][B]function[/B][/COLOR][COLOR=#009900]([/COLOR]err[COLOR=#339933],[/COLOR] fd[COLOR=#009900])[/COLOR] [COLOR=#009900]{[/COLOR]
[COLOR=#000066][B]if[/B][/COLOR] [COLOR=#009900]([/COLOR]err[COLOR=#009900])[/COLOR] [COLOR=#000066][B]throw[/B][/COLOR] err[COLOR=#339933];[/COLOR]
[COLOR=#006600][I]//console.log("The file was saved!");[/I][/COLOR]
[COLOR=#006600][I]//read back from the file[/I][/COLOR]
fs.[COLOR=#660066]readFile[/COLOR][COLOR=#009900]([/COLOR]fname[COLOR=#339933],[/COLOR] [COLOR=#000066][B]function[/B][/COLOR] [COLOR=#009900]([/COLOR]err[COLOR=#339933],[/COLOR] data[COLOR=#009900])[/COLOR] [COLOR=#009900]{[/COLOR]
[COLOR=#000066][B]if[/B][/COLOR] [COLOR=#009900]([/COLOR]err[COLOR=#009900])[/COLOR] [COLOR=#000066][B]throw[/B][/COLOR] err[COLOR=#339933];[/COLOR]
result [COLOR=#339933]=[/COLOR] data[COLOR=#339933];[/COLOR]
response.[COLOR=#660066]end[/COLOR][COLOR=#009900]([/COLOR]result[COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR]
[COLOR=#009900]}[/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR]
[COLOR=#009900]}[/COLOR]
[COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR]
[COLOR=#009900]}[/COLOR]

server.[COLOR=#660066]listen[/COLOR][COLOR=#009900]([/COLOR][COLOR=#CC0000]8124[/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR]
console.[COLOR=#660066]log[/COLOR][COLOR=#009900]([/COLOR][COLOR=#3366CC]'Server running at [URL]http://127.0.0.1:8124/[/URL]'[/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR]

And then, I ran the apache benchmarking tool on both of them with 2000 requests (200 concurrent). When I saw the time stats of the result, I was astounded:

[TABLE]

[TR]

[TD=class: code]#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[/TD]

[/TR]

[/TABLE]

The truth is out. node.js was faster than PHP by more 14 times! These results are astonishing. It simply means that node.js IS going to be THE de-facto standard for writing performance driven apps in the upcoming future, there is no doubt about it!

Agreed that the nodejs ecosystem isn’t that widely developed yet, and most node modules for things like db connectivity, network access, utilities, etc. are actively being developed. But still, after seeing these results, its a no-brainer. Any extra effort spent in developing node.js apps is more than worth it. PHP might be still having the “king of web” status, but with node.js in the town, I don’t see that status staying for very long!

References

  1. https://en.wikipedia.org/wiki/Node.js
  2. The emperor’s new clothes were built with Node.js | Notes (beta)
  3. node.js

Sursa: PHP vs node.js: The REAL statistics | Prahlad Yeri

Edited by Nytro
Link to comment
Share on other sites

Nu mi se pare cinstit testul...

<?php	set_time_limit( 0 );

$sock = socket_create(AF_INET, SOCK_STREAM, 0);

socket_bind($sock, 0, 8081);
socket_listen($sock);

function test()
{
//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);
return file_get_contents($fname);
}

while(true)
{
$client = socket_accept($sock);
socket_write($client, test());
socket_close($client);
}
socket_close($sock);
?>

Nu am efectuat comparatia, dar presupun ca este mai rapid, avand in vedere ca nu mai exista apache la mijloc, cum nici in cazul lui node.js nu exista un server web la mijloc.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...