NodeJS v PHP

July 7, 2021 . 4 MIN READ

Sometimes people link me to articles and ask for my opinions. This one was a real doozy.

Oh goody, a framework versus language post. Let’s try and chew through this probable linkbait.

This is more of a benchmark test than example.

Ok so we’re benchmarking NodeJS v PHP. Weird, but I’ll go along with it.

External library used for Nodejs was cheerio and PhpQuery for Php.

Well, now we’re testing cheerio v PhpQuery which is a bit different, but fine, let’s go along with it. These two libraries do essentially the same thing, let you parse HTML and traverse about the DOM model. I can see how one might think it’s fair, even if the title is already misleading…

Nodejs took 175.535 sec to complete where as Php took 711.790 sec to complete. Php was four times slower than Nodejs.

Sure it was, because phpQuery uses file_get_contents() which is blocking, meaning each and every single one of those web requests has to be done in turn. PHP is just sitting there waiting for the server to respond, when it could be doing something else. Also where were these tests being run from? The moon?!

We’ve come a long way from the original title of “NodeJS v PHP”, to really asking “cheerio v phpQuery”, which is realistically asking “Blocking v Non-Blocking”, or “Synchronous v Asynchronous”.

Benchmarking to see if “doing multiple things at once” is faster than “doing one thing at a time” almost certainly sounds like a waste of time, but it would at least match the actual code examples being run and therefore be a valid test. Let’s just pretend it was worded like that, and have a go at this benchmark ourselves.

Setup

I made a repo and shoved a Vagrantfile in there with just the basic Ubuntu 12.10 image. I could have done up a whole Puppet manifest, but this will be a useful learning exercise for people who want to learn how to setup ReactPHP anyway. Vagrant up that box, then ssh in. All the test scripts are in there.

I have no idea what version of PHP he is using because he doesn’t actually say, but let’s just go with PHP 5.5 ourselves because it is the current more recent stable version.

$ sudo add-apt-repository ppa:ondrej/php5
$ sudo apt-get update
$ sudo apt-get install php5-cli

That gets PHP ready.

$ sudo apt-get install -y php5-dev libevent-dev
$ wget http://pecl.php.net/get/libevent-0.0.5.tgz
$ tar -xzf libevent-0.0.5.tgz
$ cd libevent-0.0.5 && phpize && ./configure && make && sudo make install
$ echo "extension=libevent.so" | sudo tee -a /etc/php5/cli/php.ini

That should sort out libevent, so we can let PHP work with event loops.

$ sudo apt-get install -y python-software-properties python g++ make
$ sudo add-apt-repository ppa:chris-lea/node.js
$ sudo apt-get update
$ sudo apt-get install -y nodejs

This will install a version of Node much newer than the 0.6.x Ubuntu’s default repo will give you.

$ npm install request
$ npm install cheerio

Now we have the NPM modules for Node to do its thing.

Variables

Bandwidth: 15 Mbps Vagrant Memory: 1024MB PHP version: v5.5.5 NodeJS version: v0.10.21

I used phpQuery with the one file download, because they haven’t bothered getting it on Composer yet. If they’re going to flagrantly ignore PSR-0 and Composer I may as well go with performantly packaged option.

Run the Tests

$ cd /vagrant
$ chmod +x ./run.sh
$ ./run.sh

This will run the same two examples from the original article first, then run my non-blocking example put together with a little help from Chris Boden, one of the ReactPHP developers.

Results

My async re-do of the original PHP example kicked the fuck out of everything else.

Here are the numbers:

Node v0.10.21 + Cheerio

real 0m45.142s user 0m8.081s sys 0m0.888s

PHP 5.5.5 + phpQuery (Blocking)

real 3m33.601s user 0m8.685s sys 0m1.212s

PHP 5.5.5 + ReactPHP + phpQuery

real 0m23.877s user 0m10.237s sys 0m1.568s

People like pretty graphs:

Num. Seconds Passed v Page Number

Conclusions

The primary conclusion to draw from this is that doing 200 HTTP requests in sequence is slower than making multiple requests at the same time. Shocker that.

We can also be pretty confident that the original article was completely wrong about everything. PHP is not as pathetic at async code as the original “benchmark” alludes to. It is entirely down to how a package decides to implement libevent or libev, much like ReactPHP has done.

Both systems can probably go faster somehow, and both systems could probably have their API’s cleaned up some to make this even easier. They both need some fault tolerance because when I cranked up the number to 1000 both systems had problems.

I’m not going to say either system is faster, just that the massive gap in the original article comes down purely to picking a blocking system. Run it yourself, and make your own conclusions. Let’s just say that PHP is not sucking as bad as some people would expect.

https://philsturgeon.uk/php/2013/11/12/benchmarking-codswallop-nodejs-v-php/

https://medium.com/unexpected-token/10-weeks-of-node-js-after-10-years-of-php-a352042c0c11#.69rgfe5b5

https://www.quora.com/Should-I-learn-PHP-or-node-js

http://www.infoworld.com/article/2866712/php/php-vs-node-js-an-epic-battle-for-developer-mind-share.html

https://www.sitepoint.com/sitepoint-smackdown-php-vs-node-js/

Leave a Reply

Your email address will not be published. Required fields are marked *