Skip to content

Instantly share code, notes, and snippets.

@nkt
Last active September 27, 2023 08:24
Show Gist options
  • Save nkt/e49289321c744155484c to your computer and use it in GitHub Desktop.
Save nkt/e49289321c744155484c to your computer and use it in GitHub Desktop.
ReactPHP vs Node.js
var http = require('http');
var data = {
'code': 'ok',
'error': false,
'payload': 'Hello World'
};
var app = function (req, res) {
res.writeHead(200, {
'Content-Type': 'application/json'
});
res.end(JSON.stringify(data));
};
var server = http.createServer(app);
server.listen(1337, function() {
console.log("Server running at http://127.0.0.1:1337");
});
<?php
require 'vendor/autoload.php';
$data = [
'code' => 'ok',
'error' => false,
'payload' => 'Hello World'
];
$app = function ($request, $response) use($data) {
$response->writeHead(200, array('Content-Type' => 'application/json'));
$response->end(json_encode($data));
};
$loop = new React\EventLoop\LibEventLoop();
$socket = new React\Socket\Server($loop);
$http = new React\Http\Server($socket, $loop);
$http->on('request', $app);
echo "Server running at http://127.0.0.1:1337\n";
$socket->listen(1337);
$loop->run();

wrk -t4 -c400 -d10s http://127.0.0.1:1337/

PHP

Running 10s test @ http://127.0.0.1:1337/
  4 threads and 400 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     7.02ms    6.94ms  82.86ms   85.27%
    Req/Sec   827.17    552.85     2.38k    66.54%
  22543 requests in 10.07s, 3.61MB read
  Socket errors: connect 151, read 22680, write 86, timeout 0
Requests/sec:   2238.19
Transfer/sec:    367.20KB

Node

Running 10s test @ http://127.0.0.1:1337/
  4 threads and 400 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    20.34ms    4.50ms 125.04ms   97.89%
    Req/Sec     3.09k     1.93k    6.06k    55.00%
  122838 requests in 10.02s, 23.66MB read
  Socket errors: connect 151, read 69, write 73, timeout 0
Requests/sec:  12263.37
Transfer/sec:      2.36MB
@embluk
Copy link

embluk commented Feb 1, 2018

How real are these Swoole benchmarks and is ReactPHP falling behind because it is a pure PHP implementation and Swoole is using C/C++?

@MarcFaussurier How come the PHP 7.3 benchmark with JIT enabled is much slower than 1st place? Is it because the JIT is in development still?

@robertkraig
Copy link

@MarcFaussurier how does that compare with the newest version of nodejs?

@Wulfklaue
Copy link

Wulfklaue commented Feb 17, 2018

Here are some of my results:

Windows 10 64Bit
32GB 2400 ECC Memory
i5 6 Cores @ 4.7Ghz. No HT!

Results:

NodeJS ( Windows Root - Without Cluster ):

14,930.33 [#/sec] (mean) ( maxing 50% CPU usage )

NodeJS ( Windows Root - With Cluster 6 threads = match CPU ):

14.999.51 [#/sec] (mean) ( maxing 55% CPU usage ) << Seem hitting a wall somewhere

Crystal ( WSL )

80,306.77 [#/sec] (mean) ( maxing 65% CPU usage )

Swoole + PHP 7.0 ( WSL ... Automatic 8 threads active ) :

111,661.30 [#/sec] (mean) ( 99% CPU usage )

Go ( WSL ):

138,823.71 [#/sec] (mean) ( 99% CPU usage )

Go ( Windows Root):

196,741.68 [#/sec] (mean) ( 99% CPU usage )

Note: Apache Bench is eating almost 10 a 20%...

WSL:

As you can tell from the Go tests, WSL eats a heft chunk of performance. But even with the performance degradation Swoole+PHP is still 8 Times faster.

Node

While yes, NodeJS was only hitting 50% CPU usage, it had access to the pure Windows Root. As we see with the Go benchmarks, WSL easily eats 1/3 performance. For some reason NodeJS in cluster mod was still being limited. Tried NodeJS under WSL = Socket issues.

Careful

But Swoole has a few points you need to be careful about. I noticed massive memory leaks from a custom framework until i figure out its because PHP did not properly clean up in specific situations.

For instance, do NOT use: register_shutdown_function, set_error_handler, set_exception_handler and self registering classes. Avoid global (always a good tip).

Unfortunately the link is in Chinese because well ... the Swoole developers are Chinese. Also part of the reason why few people know it in the West.

Link to Chinese Google translated Docs

@embluk

Swoole is using C if i remember correctly. And those results are real... I have done my own simple "hello world" benchmarks, benchmarks with my custom framework from work ( see below ) and with some preliminary database access. Because i am lazy and run this under Windows Linux layer, it also affect performance but even then Swoole kicks ass.

@subpardaemon:

I tried under Windows WSL using Sqlite ( connect, create table if not exist, insert values, read values ) with a in-memory database ( because WSL file access is horrible slow ) and i was hitting 38.000 req / second with ease. And that is with the default PHP Sqlite driver. It has no aync support as the Mysql driver that Swoole has included.

My custom framework ( that leaked memory because of the issues mentioned above ) without database access ( routing, Dependency injection, logging, and lots of other activity ) was doing 103K req/sec. So almost no slowdown compared to raw Hello World.

And this framework was simply quickly stripped of DB access ( because WSL is so slow for file access, i did not want to contaminate the results ), its a actual production Rest framework that i use at work. Its technically not Swoole idiomatic designed. The whole rooting i can fall back on Swoole for that. I "cheated" by:

    $_SERVER['REQUEST_URI'] = $request->server[ 'request_uri' ];
    $_SERVER['REQUEST_METHOD'] = $request->server[ 'request_method' ];
    $_SERVER['REMOTE_ADDR'] = $request->server[ 'remote_addr' ];

Because Swoole by itself does not fill up that data.

Conclusion:

Its a impressive piece of tech, allowing a person to run PHP almost at full blown compiled language speeds. With some precautions how you program.

How tested is it? Well, i know that Tencent uses it. Tencent = WeChat ... The Chinese equivalent of WhatApp.

https://github.com/Tencent/tsf

Going to do more testing but i frankly think this is the direction that PHP needs to go, if they want to stay relevant in the future. Optimize PHP, not unloading PHP after each request, fix the memory issues. Its especially that last part, what is massive killing most scripting languages their performance, the fresh start with each request. And the IO blocking.

I know that PHP 8.0 has a JIT experimental engine but its simply the wrong direction. Do not try to speed up the loading, prevent the unloading and blocking issues.

@d4wae89d498
Copy link

@embluk Yes thats it, JIT is purely for development purpose for now and it still doesn't bring any performances gain yet, but it looks pretty nice for a "master" branch ! I'm sure that the production release will be amazing.

@robertkraig I will test with nodejs 9 once i'll get at home ;)

@RWOverdijk
Copy link

Thanks for sharing all the results. It's really interesting.

@sinasalek
Copy link

@ifubar They both used the same number of CPU cores. Also note that raw swoole performance is in pair with nginx!! i couldn't believe it but i ran it several times and the result was consistent! Also note that in real world applications the difference is much less but nonetheless it proves that php can now be used even as a static file server!

@bawasaab
Copy link

@arunnabraham
Copy link

checkout the below one

https://medium.com/@mtrdesign/reactphp-6c65735138a0

https://reactphp.org/

React is good but no where near fast as Swoole

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment