[Из песочницы] PHP 7.1.1 FPM vs Node.js 7.4.0 в качестве web backend сервера

Всем привет, решил поделиться с вами результатами синтетического теста производительности свежих версий PHP и Node.js.

Конфигурация сервера:

Простой VDS — 1 ядро процессора 2ГГц, 1Гб оперативы, 10Гб SSD.
ОС: Debian 8.6.
Так же произведены базовые настройки ядра, чтобы сервер в принципе мог обрабатывать большое кол-во соединений.

Испытуемые:

— PHP 7.1.1 FPM
 — Node.js 7.4.0

Первый этап:

Тут операции, которые в основном использует backend. А именно: склеивание строк, сетевой ввод-вывод, арифметика и работа с массивами.

Код для Node.js:

var fs = require('fs');
var mysql = require('mysql2');

console.time('Node.js ' + process.version + ': склеивание строк 1000000 раз');
var str = '';
for (var i = 0; i < 1000000; i++) {
	str += 's';
}
console.timeEnd('Node.js ' + process.version + ': склеивание строк 1000000 раз');


console.time('Node.js ' + process.version + ': сложение чисел 1000000 раз');
var count = 0;
for (var i = 0; i < 1000000; i++) {
	count++;
}
console.timeEnd('Node.js ' + process.version + ': сложение чисел 1000000 раз');


console.time('Node.js ' + process.version + ': наполнение простого массива 1000000 раз');
var array = [];
for (var i = 0; i < 1000000; i++) {
	array.push('s');
}
console.timeEnd('Node.js ' + process.version + ': наполнение простого массива 1000000 раз');


console.time('Node.js ' + process.version + ': наполнение ассоциативного массива 1000000 раз');
var array = {};
for (var i = 0; i < 1000000; i++) {
	array['s' + i] = 's';
}
console.timeEnd('Node.js ' + process.version + ': наполнение ассоциативного массива 1000000 раз');


console.time('Node.js ' + process.version + ': чтение файла 100 раз');
var content;
for (var i = 0; i < 100; i++) {
    content = fs.readFileSync('./someFile.txt');
}
console.timeEnd('Node.js ' + process.version + ': чтение файла 100 раз');


console.time('Node.js ' + process.version + ': mysql query (SELECT NOW()) 100 раз');
// create the connection to database
var connection = mysql.createConnection({host:'localhost', user: 'root', database: 'test', password: 'password'});

function promiseQuery(query) {
    return new Promise((resolve, reject) => {
            connection.query(query, function (err, results, fields) {
            resolve({err, results, fields});
        });
	});
}
for (var i = 0; i < 100; i++) {
    var a = promiseQuery('SELECT NOW()');
    a.then(({err, results, fields}) => {
        //console.log(results);
    });
}
console.timeEnd('Node.js ' + process.version + ': mysql query (SELECT NOW()) 100 раз');
connection.end();

Код для PHP:
query("SELECT NOW() as `now`");
	$now = $res->fetch_assoc()['now'];
}

echo "PHP $phpVersion: mysql query (SELECT NOW()) 100 раз: " . round((microtime(1) - $start) * 1000, 3) . "ms \n";

Результаты:

image

Как видно, PHP выигрывает по всем пунктам, кроме операции сложения.

Второй этап:

Нагрузочное тестирование «Hello world». Nginx 11.7 + PHP 7.1.1 FPM vs Node.js. 1000 запросов в 1000 потоков. #ab -n 1000 -c 1000…

Код PHP:



Код Node.js:
const http = require('http');

const hostname = '127.0.0.1';
const port = 3000;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello World');
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

Результаты

Прогнал по 10 тестов для PHP и для Node.js и выбрал лучшие результаты у обоих.

Node.js:

image

PHP:

image

Как видим и тут PHP выигрывает на 23% или на 628 запросов в секунду. Много это или мало судить вам.

Делитесь в комментах своими мыслями по этому поводу.

Комментарии (3)

  • 28 января 2017 в 03:10 (комментарий был изменён)

    0

    В первых тестах вы не используете FPM, а используете zts cli версию. А во второй пачке тестов, думаю, корректнее было бы сравнивать Ratchet + PHP, а не Nginx + PHP.


    P.S. Моё личное мнение, преимуществ у ноды две: Это наличие асинхронного апи (а не кусками, как в пыхе) и поддержка в браузерах.

  • 28 января 2017 в 03:33

    0

    У меня из командной строки получился обратный результат:

    >c:\php\php test.php
    PHP v7.0.4: concatenation 1000000 times: 132.97ms
    PHP v7.0.4: addition 1000000 times: 174.055ms
    PHP v7.0.4: adding to array 1000000 times: 154.771ms
    PHP v7.0.4: adding to hash 1000000 times: 249.67ms

    >node test.js
    Node.js v6.9.4: concatenation 1000000 times: 50.109ms
    Node.js v6.9.4: addition 1000000 times: 2.692ms
    Node.js v6.9.4: adding to array 1000000 times: 22.845ms
    Node.js v6.9.4: adding to array hash 1000000 times: 877.773ms

    Частично соглашусь с предыдущим комментарием: ноде нужен только для асинхронности и событийности. А вообще писать для него не самое приятное занятие.

    • 28 января 2017 в 03:44

      0

      В тесте adding to hash если заменить
      array['s'+i] = 's';

      на
      array[''+i] = 's';

      то результат улучшается с 877.773ms до 203.794ms, а если на 
      array[i] = 's';

      то до 34.362ms
      Интересно почему…

© Habrahabr.ru