Как стать автором
Обновить

Комментарии 92

По картинкам видно, что генерируется разный ответ, даже разный размер страницы, тесты не одинаковые! Еще и не понятно как запускается NodeJS в дебаг режиме или в релизе, а от может зависит и скорость.
А какие у вас результаты?
Nginx отправляет заголовки отличные от тех что отправляет модуль http в ноде, вот и все дела
https://github.com/mazabenchmarks/NodeVsPHP/blob/master/rest_api.js
function mysqlQuery(query, cb) {
    connection.query(query, function (err, results, fields) {
        cb({err, results, fields});
    });
}

function generatePage(res) {
    const time = process.hrtime();
    mysqlQuery("SELECT * FROM `users`", ({err, results, fields}) => {
        let response = JSON.stringify(results);
        const diff = process.hrtime(time);
        const generationTime = diff[1] / 1000000;
        response += `<div><b>Страница сгенерирована за: ${generationTime}ms</b></div>`;
        res.end(response);
    });
}

а зачем вы столь извращенно завернули обращение к базе в «свой апи»?
вы же этим кодом вставляет палки в колеса JIT'у.

почему нельзя было сделать так?:
function generatePage(res) {
    const time = process.hrtime();
    connection.query("SELECT * FROM `users`", function (err, results, fields) {
        let response = JSON.stringify(results);
        const diff = process.hrtime(time);
        const generationTime = diff[1] / 1000000;
        response += `<div><b>Страница сгенерирована за: ${generationTime}ms</b></div>`;
        res.end(response);
    });
}
На ноде никто так не делает, делают примерно вот так:
const Promise = require('bluebird')
const mysql = require('mysql')
const pool = mysql.createPool({
    host: 'localhost',
    user: 'root',
    password: 'pwd',
    database: 'test',
    connectionLimit: 100
})
pool.query = Promise.promisify(pool.query)

function generatePage(res) {
    const time = process.hrtime()
    pool.query(`SELECT * FROM 'users'`)
        .then(results => {
            let response = JSON.stringify(results)
            const diff = process.hrtime(time);
            const generationTime = diff[1] / 1000000;
            response += `<div><b>Страница сгенерирована за: ${generationTime}ms</b></div>`
            res.end(response)
        })
        .catch(err => console.log(err))
}

С пулом коннектов еще лучше.
Я не node.js дев, потому лишь указал на явный косяк в коде.
НЛО прилетело и опубликовало эту надпись здесь
Идею я понимаю, но не поддерживаю:
1. если не преследуется цель написать DAL, чтобы потом можно было менять имплементацию коннектора, то смысла в этом нету.
2. в версии ПХП этого теста, даже функций нету — сплошное полотно.

Если была цель сделать как в реальной системе — были бы модули, подключался хотя бы PDO, а не функция mysqli, которая еще с php4 тянется в коре.
А так, это похоже на попытку написать код так, чтобы он просто работал хуже.
mysqli работает быстрее. В моих тестах PDO дает более медленный результат — на 100 запросов в секунду
Честно говоря, я не понимаю вашей цели.
В реальных проектах на php уже давно не пишут простыню кода. И уж тем более не делают смесь html + php + sql, как это будет у вас при вашем текущем подходе.

Измерять скорость работы в попугаях в двух задачах, которые даже близко не лежали с реальными — зачем? Ради холивара? — ок, вам это получилось. Ради правды? — так вы не узнаете ничего.

И снова таки: если вам нужна производительность системы — возьмите платформу, которая даст производительность из коробки — компилируемые языки такие как C#, Java, Scala, Go.

ps: а задачи php и node.js в целом не схожи между собою: php нацелен на CPU-bound обработку, node.js — на IO-bound. В нормальной системе было бы хорошо даже совмещать их, нежели пихать невпихуемую логику в конкретную из платформ.
Как я и говорил выше, когда писал вопросы и ответы, с пулом результат хуже, а конкретно лучшее что чего мне удалось добиться за 10 прогонов это 380 запросов в секунду…

Кусок кода
const mysql = require('mysql2');
const Promise = require('bluebird');
const http = require('http');

const pool = mysql.createPool({
    host: 'localhost',
    user: 'root',
    password: 'pwd',
    database: 'test',
    connectionLimit: 100
});
pool.query = Promise.promisify(pool.query);

function generatePage(res) {
    const time = process.hrtime();
    pool.query('SELECT * FROM `users`')
        .then(results => {
            let response = JSON.stringify(results);
            const diff = process.hrtime(time);
            const generationTime = diff[1] / 1000000;
            response += `<div><b>Страница сгенерирована за: ${generationTime}ms</b></div>`;
            res.end(response)
        })
        .catch(err => console.log(err))
}


connectionLimit пробовал ставить разный и 10 и 50 и 100 и 1000. Лучший результат — 380 запросов в секунду…
Это потому что ваш тест говно, прощу прощения за мой французкий

На каком месте пукан бомбануло?)

НЛО прилетело и опубликовало эту надпись здесь
С массивами пхп работает в разы быстрее, я уже проверял
https://habrahabr.ru/post/320670/ вот статья
По ссылке:
node 7.3.0
test3 (array): 53.455ms

php 7.1.1
test3 (array): 63.453ms

То есть php не «в разы быстрее», а медленнее

С этим «тестом» та же история, только новичков пугать, не зря минусуют. Или кто-то верит, что существуют приложения без пост обработки данных после получения их с базы данных? Добавить немного логики в вычисления, и красивые цифры в пользу php разрушаться
Да да да, конечно же.
Кстати, как вариант сделать чтение из файла
С простой логикой, вроде подсчёта возрастов, или подсчёта людей по полам
Тогда исключим влияние сторонних библиотек
Я бы ещё заметил, что добавление к строке в цикле
for (let i = 0; i < results.length; i++) {
    response += `<span>Hello <i>${results[i].login}!</i> </span>`;
}

это не то же самое, что просто выплёвывание строки через echo в случае с PHP
while ($row = $res->fetch_assoc()) {
    echo "<span>Hello <i>{$row['login']}!</i> </span>";
}

Склеивание строк — не самая дешёвая операция. А скорость работы через echo в свою очередь зависит от буферизации ответа.
Альтернатива?
НЛО прилетело и опубликовало эту надпись здесь
Завтра напишу какой результат по скорости с такой реализацией
Результат ещё хуже, за 10 прогонов подряд лучший результат — 150 запросов в секунду…
С ходу не скажу, т.к. боюсь наврать. В работе Node.js с буфером ответа не разбирался. Но в качестве лобового решения предложил бы следующее:
1. Прикрутите в PHP переменную и склеивайте в неё ответ как в случае с Node.js
2. А зачем вам вообще Nginx? Запустите в консоли два скрипта и измеряйте их скорость.
1. Зачем если есть стандартный способ вывода? Надо node.js сделать по аналогии, выплевывая в аутпут. А конкатенация строк в php кстати очень быстрая: https://www.urbaninsight.com/performance-test-string-concatenation-php (да, еще один сферический тест в вакууме).
2. Зачем убирать nginx? Лучше же когда конфиг максимально близок к работающему в боевом режиме.
1. Ну у меня больше опыта с PHP, в Node.js не знаю тонкостей. Если можно сделать эквивалентные способы, то пожалуйста.
2. Боевые конфиги тоже бывают разными. Тут просто надо определиться, что тестируем. Если сферическое приложение, то лучше бы добавить хотя бы шаблонизаторы. Если скорость взаимодействия с nginx (что довольно бредово, но тестировать можно всё что угодно), то надо выкидывать базу данных. Если скорость отрисовки строк, вынутых из mysql, то nginx не нужен.

Похоже вы не поняли смысл теста и что именно тестируется, прочитайте текст внимательнее. Сравнение 2х примеров реального приложения. Какой язык заставит пользователя меньше ждать результата от сервера.

Не знаю как у вас язык повернулся назвать это «реальным приложением». Типичный сферический конь.

И медленный ответ сервера может значить в равной степени и его кривую настройку. Почему я вам выше и предлагал пустить два чистых скрипта без nginx и сравнить результаты. Ну или добавьте на гитхаб конфиги nginx'а хотя бы.

И, честно говоря, судя по вашим комментариям, у вас нет цели разобраться в том, почему так происходит. За что вас, собственно, и поливают грязью. Одно дело сделать исследование вида «чёрный ящик А работает быстрее чем чёрный ящик Б в сферической задаче Х» и совсем другое разобраться, почему так происходит. Если бы вы провели глубокое исследование по любому участку, начиная со склеивания строк и заканчивая коммуникацией с базой, сравнили бы работу через unix-сокеты с проксированием запроса nginx'ом на другой порт и прочее и прочее, то эффект был бы другим. Пока вы просто плюнули в Node.js с применением странной задачи. Как думаете, убедили ли вы кого-нибудь в своей правоте? Извлёк ли кто-то пользу из вашей стати? Вы сами для себя в чём-то стали лучше разбираться? Пока кажется, что вы просто хотите похоливарить. Как развлечение это годиться, но пользы от этого никому нет. Топик утонет в сотнях таких же непонятных тестов, которые поверхностно показывают что на взятой с потолка задаче побеждает любимый язык автора.
Мне равноценно нравятся 2 этих языка, я обновил результаты в статье с использованием другого драйвере mysql в ноде, и теперь нода лидирует
Хорошо что вы делаете работу над ошибками. Но повторю мысль, которую вам тут уже высказывали неоднократно. Если хотите предоставить широкой общественности свои тесты производительности — разбирайтесь глубже. Теперь мы хотя бы знаем, что глобально проблема была в sql-библиотеке. Но нет придела совершенству.
Какой язык заставит пользователя меньше ждать результата от сервера.

Уж если на то пошло, то не язык, а платформа. Язык никого ждать не заставляет.

#ab -n 3000 -c 1000…

Никогда не понимал, зачем такакя конкурентность большая в тестах. :)
Разве столько клиентов придет одновременно?

Ну а по теме:
Используем PHP 7.0, преимуществ в 7.1 не вижу. Хз, есть ли для него тот же memcached.
Но PHP используется, потому что так исторически сложилось.
Ну и код просто на нем пишется.
А NodeJS — это чуток другой подход, вся эта асинхронность, чтобы не наделать случайно синхронности.
Да, оно красиво, может и быстрее работает, но лень разбираться. :)
Работает медленнее чем пхп) а пхп 7.1 быстрее чем 7.0 значительно)
Сильно сомневаюсь, что значительно. Вот с php 5.3 на 7.0 это значительно. С 7.0 на 7.1 на реальных приложениях ни значительного ускорения, ни заметного снижения потребления памяти.
Если сомневаешься, есть только 1 правильный вариант, взять и проверить самому ;)

На мой взгляд вы сравнили скорость работы драйверов MySQL для nodejs и php7, а не сам бэкенд.

Да, я все всех обманываю. Только берешь мой код, запускаешь, смотришь цифры и убеждаешься в том, что тесты не врут
Нет, не обманываете, а прикидываетесь что не понимаете о чем речь:
кто-то верит, что существуют приложения без пост обработки данных после получения их с базы данных? Добавить немного логики в вычисления, и красивые цифры в пользу php разрушаться

Поэтому ваш код брать даже смысла нет, потому что он ничего не делает

Но если вы настаиваете, что такие бывают, то всё еще проще, для таких приложений уровня как вы тестируете совершенно не важно что брать, потому что там не будет больше 2х человек в месяц
Любая постобработка быстрее в пхп, поэтому без разницы, все равно пхп обгонит)
node 7.3.0 vs php 7.1.1:
test1_node (str): 67.853ms 
test1_php (str): 83.961ms

test2_node (sum): 8.685ms 
test2_php (sum): 69.857ms

test3_node (array): 53.455ms 
test3_php (array): 63.453ms

«обогнал» так обогнал, только пятки видны.
При этом чем больше логики (то есть чем приложение больше приближено к реальному), тем слабее позиции php. Но можно и дальше закрывать на это глаза и прогонять «пустые» тесты без логики
Давай так, посмотри код для теста REST API для Node.js, перепиши его так, чтобы результат приблизился к ПХП. И приложи его сюда, в комментарии. Я замерю скорость и скажу результат, если твой код окажется быстрым, то я только буду рад, я люблю и Node.js и PHP, поэтому не отношусь предвзято к какому-то из них, а основываюсь только на экспериментах и фактах.
Только собралась собирать тестовый стенд, как вы уже сами подтвердили, что php медленнее, хотя я и так об этом говорила уже

Если добавить к тестам логики, то php отстанет еще сильнее

Php Был первым, и простым.
Но если, не завезут Jit, много-поточность, асинхронность, connection pool, технология постепенно вымрет.
Я сам только писал на php, с nodejs,python,C# только баловался.


Вопрос сколько php будет вымирать ))
Жаль конечно что существуют еще люди которые верят что php Rules!


Php архитекторам надо надо Libuv внедрять!
Так как новый net core так и сделал !

Тесть вас не волнует скорость работы приложения? Главное чтобы язык был модный и новый?

Здесь стайная система. Если у вас нет своей стайки — будете на минусе. У вас даже одинаковое колличество минусов и плюсов ровно столько же у ваших оппонентов. Карма в этом случае ничего не значит. Они захватывают аудиторию.
Угу…
Не холивара ради, но сколько лет я слышу уже что пхп вот-вот вымрет… а он таки живее всех живых, а вымирают лишь модные(появился захайпился и сгорел аки мотылек через условные(!) пару лет) фреймворки\языки, причем пачками :)

толстый тролль

Конечно круто, а где конфиги?

Мне пых не нравится по определению.
Поэтому я промолчу про кривые тесты в сферическом вакууме.

Сама по себе идея провести подобное тестирование – хорошая, но это надо делать в лабораторных условиях, гарантировав их идентичность и равное положение обоих испытуемых, а в текущей версии это просто вброс какой-то.
Ответ: На одно ядреном процессоре будет медленнее. (Проверено неоднократно)

Вначале вы говорите:
Сегодня у нас будет более честное сравнение, которое отображает большинство реальных задач.

Но разве делать сервис, с серьёзными требованиями к производительности, на таком железе «отображает большинство реальных задач»?
НЛО прилетело и опубликовало эту надпись здесь
Вы возможно не знаете что в PHP 1 запрос = 1 процесс? Т.е. с ростом кол-ва ядер процессора, будет расти производительность, как у пхп, так и у ноды(запущеной в кластере само собой, она ведь однопоточная)) Какие мы можем сделать выводы? Результаты будут такими же, только циферки увеличатся. Вам никто не мешает доказать обратное(прежде всего самому себе). Арендуйте многоядерный сервер, установите Nginx, PHP 7.1.1-FPM и Node.js 7.7.1, скопируйте из репозитория мой код, прогоните тесты и увидите результат сами. Лучше проверить на практике, чем проводить эксперименты в уме. Конфиг ПХП сейчас добавлю в репозиторий
varnish сравняет счет, так что смысла в таком сравнении нет
а для числодробилок лучше что-нибудь другое использовать
накинулись все… как же так, немодный php оказывается не такой уж и медленный =)
по самим тестам необходимо указывать конфигурации. например, включен ли opcache
Конечно же включен, он даже из коробки включен)
НЛО прилетело и опубликовало эту надпись здесь
Разные приложения? приложения абсолютно одинаковые, разных только 2 языка, которые реализуют выполнение одной и той же работы.
Архитектура у приложений разная. На JS надо писать синхронно, чтобы сравнивать с классическим PHP. Или наоборот, на PHP асинхронно. Если, конечно, есть желание сравнивать языки, а не архитектуры. А по хорошему четыре варианта сравнить с синхронным и асинхронным ио на пхп и джс. Возможно выводы будут типа: php быстрее в синхронной модели, а джс в асинхронной.
Какая разница? Суть одна, быстрее испытуемый А или испытуемый Б. Я например не люблю долгую задержку ответов от сервера, меня прям бесит, поэтому для меня важна скорость работы того, что я пишу.
Напиши как угодно и с любыми хаками, если это поможет обогнать другой язык, то это просто супер.

Нет ни одна. У вас суть "при использовании A способом B он быстрее чем C при использовании способом D". Но из этого нельзя сделать вывод будет ли при использовании C способом B быстрее или нет. О том, стоит ли сложность C этого ускорения можно ещё поговорить.

НЛО прилетело и опубликовало эту надпись здесь
Для следующего проекта возьму и то, и другое. На PHP — сервисы с HTTP REST like API, на NodeJS — HTTP GraphQL API Gateway, серверный рендеринг React и транслятор событий RabbitMQ в веб-сокеты.
Прежде чем начать кодить, сравни производительность рендеринга php с серверным рендерингом реактка. И было бы интересно узнать результат, т.к. эти технологии я не сравнивал сам.
если вы так стремитесь за производительностью, то почему вы взялись сравнивать две не самые то и быстрые технологии? почему не взяли более быстрые: C#, Java, Scala? зачем именно этот холивар между php и node.js?
Во первых, с чего вы взяли, что эти языки будут быстрее PHP в конкретных 2х примерах которые я привел? Вы замеряли производительность? Если нет, то можете написать код на любом из этих языков, я запущу его на своей машине и скажу результат.
Во вторых, я решил сравнить именно эти 2 очень популярных языка и не вижу в этом ничего плохого.
В третьих, если мне нужна реальная скорость, я напишу это на СИ) Ибо, зачем прибегать к полумерам в виде C#, Java, Scala, Go и т.п. в таком случае)
В третьих, если мне нужна реальная скорость, я напишу это на СИ

Вот вы и ответили самому же себе, почему сравнение "что быстрее — PHP и node.js" лишено большого смысла.

Действительно, ведь на си писать быстрее и легче.

… осталось распространить эту аргументацию на ваш пост.

А мне производительность не настолько важна, чтобы поддерживать логику рендеринга на двух языках (клиентский рендеринг React точно в проекте будет) или писать бизнес-логику на JS. От этих двух языков я беру, прежде всего, лучшую скорость разработки в соответствующих задачах.

А когда будут тесты по скорости и стоимости РАЗРАБОТКИ кода?  +1 разраб в команду равен +20 средних серверов в аренду. Нахрена считать железо и язык если не ясно сколько стоит разработка?

Долго пытался понять, зачем в коде запроса к BD используется деструктуризация аргументов (причем в обе стороны), но так и не смог. Видимо, чтобы сделать код специально медленнее. И тем более в тесте на скорость странно видеть let а не var. Это тесты из серии — когда очень хочется, чтобы любимый язык победил?

Аааа, я понял! let и const ввели специально чтобы чтобы скорость работы JS упала в 2-4 раза. Ну тогда все просто, нужно просто все поменять на var и тогда нода победит, расходимся).

А ещё, если я все запросы в БД замeню на
SELECT `id` FROM `users` WHERE `id` = 1
и тогда нода будет будет работать с базой в 15 раз быстрее, чем пхп!!!
А я то думаю, как же так, почему такая значительная разница в скорости…
  1. let до сих пор не оптимизирован в циклах, потому обычно его там не используют.
  2. Так что там с деструктуризацей, зачем аргументы загонять в объект и потом обратно разворачивать этот объект? Какой сакральный смысл то?
Эммм, медленный кусок кода пожалуйста напишите. И напишите ваш аналог, чтобы было все по честному, и я запущу тест и скажу результаты.
Когда то тоже писял кипятком от скорости NODE.js в случаях когда сервер должен выдержать десятки тысяч реквестов на API который в принципе ничего сложного не делает кроме как выплюнуть малюсенький json. После написания нескольких проектов, которые немного сложнее чем тысячи трехстрочных примеров в интернете, типа идем в базу, берем что-то и выплевываем JSON, я очень надеюсь что когда-нибудь это какашка (nodejs) умрет.

Как только в приложении появляется бизнес логика (привет коллбэкам), как только с данными нужно проводить операции которые занимают процессорное время (привет однопоточности) а не только асинхронный io, начинаются пляски с промисами, асинк и т.д. (асинк эвэйт из той же серии) и разработка превращается в ад и Израиль.

Не ведитесь на цифры, они далеко не фактор. Я уже не говорю о нормальных разработчиках которые реально понимают разницу между Parallel vs Concurrent.

Я все еще пишу на ноде, но очень маленькие прототипы с минимум логики, микросервисы можно сказать. Когда нужно писать что нибудь серьезное, понимаешь что тебе не хватает управления твоей же программой. Хочется самому решать в каком потоке и что запускать, синхронизировать, и т.д. Хочется писать нормальный синхронный код и не тратить время на понимание каши которую сам же и написал 5 минут назад, и строить в голове граф из колббэков, прромисов и т.д.

В тоже время PHP я вообще не использую для написания миркосервисов (ну не его это ниша). Если программеры нормальные, PHP это отличное решение для быстрой веб-разработки, особенно для стартапов. Масштабируется PHP тоже очень хороше. А то что работает медленно, можно вынести в микросервис.

И вот тут у меня большие надежды на GO. Писать микросервисы одно удовольствие. GO дает достаточно высокоуровневого API, и в тоже время. у программиста есть возможность использовать низкоуровневые плюшки (мьютексы и т.д.).

P. S.
На неделе исправил баг в системе, когда CRM умирал (LAMP стэк). После рисерча, нашелся код, от одного разраба который работал в компании в 2015 году. Там было (это я еще почистил от мусора):

//Задача — найти все депозиты конкретного клиента

function findUserDeposits($user_id)
{
    $deposits = $this->getAllDepositsFromDatabase(); // SELECT * FROM transactions
    $transactions = $this->deepCopy($deposits); // deep copy of $deposits array data to new array with array key as row id from database

    $results = [];

    foreach ($transactions as $transaction) {
        if (('' . ($transaction['user_id'])) !== ('' . $user_id)) {
            continue;
        }
        
        $id = $transaction['id'];
        $result[$id] = $transaction;
    }

    return $results;
}


Не трудно догадаться почему все умерло… Когда я это увидел у меня скатилась слеза…

Что-то мне подсказывает, дай этому разрабу вместо php, какой-нибудь С или JAVA, ничего бы не изменилось. А вой дай ему NODEJS с коллбэками, то я даже представить не могу что бы он там наколбасил. А вы тут микросекунды считаете. Я сам как инженер люблю цифры, но вот пришел к понимаю того, что это далеко не главное, во всяком случае не там где эти цифры нам показывают в тестах.

Вот померять скорость обработки изображения например — тут реально есть что мерять и сравнить разные тулзы и языки. А взять с базы, выплюнуть JSON или html страничку, и замерять это — вот уже действительно трата времени.

Сколько алгоритмов из этого теста вы применяете? :D

Замените mysql2 на https://github.com/mscdex/node-mariasql/ — на вашем же примере у меня время генерации 0,6 ms, против 1,1ms у PHP. Что в иной раз доказывает, что этот тест лишь сравнивает либы по подключению к mysql.
Сейчас заменю и проверю
Вот результаты тестирования mysql либ для Node.js по сравнению с PHP — http://mscdex.github.io/node-mysql-benchmarks — думаю теперь вы понимаете, почему PHP быстрее именно в вашем тесте?
Все верно, я не знал о существовании этого драйвера. Сейчас обновлю результаты, теперь Node.js впереди!)
все комментарии выше именно про это и говорили(
Ну вот, теперь осталось Вам понять, как ускорить php))
На самом деле, чтобы статья стала чуть более «уважаемым», надо добавить результаты профилировщика
Понять, где эти узкие места

И сказать, допустим, «вот из-за этой стандартной операции 1+1 php быстрее node»
или «из-за своей асихнронной модели нода оказалась чуть круче чем php в таких-то и таких-то задачах»
Это и послужит выводом, потому что сейчас его нет.

А завтра вы узнаете что в PHP есть Постоянные соединения. И он догонит, а потом я вам дам, свой форк mariasql и nodejs будет снова в лидерах.


А итог такой, ваш тест, тестирует только ваши знания и ничего больше.

На пыхе писал, на пыхе пишу, на пыхе и дальше буду писать, пока не понадобится что-то отличное от веб-приложения.

Веб-сокеты на пхп в продакшене запускали? Какая нагрузка, сколько нод в кластере, утечки памяти мониторите? Пререндеринг на пхп для JS-фреймворков типа ангуляра или библиотек типа реакт как на пхп делаете?

По поводу конфигов системы, пхп, Mysql
У меня настроено так, чтобы работало максимально быстро.
Если вы не знаете как должна быть настроена операционная система, php, nginx и mysql. Это не моя проблема.

Несерьезный какой-то подход. А если у вас там запросы кэшируются или еще что? Может вы просто node vs nginx протестировали.
Залейте конфиг nginx в репозиторий хотя-бы.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации