Неожиданный исход узла.js vs ASP.NET проверка производительности ядра
я делаю быстрый стресс-тест на двух (своего рода) hello world проектов, написанных в узел.js и asp.net-core. оба они работают в рабочем режиме и без подключенного к ним регистратора. Результат поразительный! ASP.NET ядро опережает узел.js приложение даже после выполнения некоторых дополнительных работ в то время как узел.приложение js просто отображает представление.
Приложение 1: http://localhost:3000/nodejs
node.js
используя: узел.Яш, экспресс и ваш движок.
код в этой конечной точки
router.get('/', function(req, res, next) {
var vm = {
title: 'Express',
time: new Date()
}
res.render('index', vm);
});
как вы можете видеть, он ничего не делает, кроме отправки текущей даты через time
переменная для представления.
Приложение 2: http://localhost:5000/aspnet-core
asp.net core
используя: ASP.NET ядро, шаблон по умолчанию таргетинг dnxcore50
однако это приложение делает что-то другое, чем просто рендеринг страницы с датой на нем. Он генерирует 5 абзацы различных случайных текстов. Это теоретически должно сделать это немного тяжелее, чем приложение nodejs.
вот метод действия, который отображает эту страницу
[ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)]
[Route("aspnet-core")]
public IActionResult Index()
{
var sb = new StringBuilder(1024);
GenerateParagraphs(5, sb);
ViewData["Message"] = sb.ToString();
return View();
}
результат стресс-теста
узел.результат стресс-теста js App
обновление: следуя предложению Горги Косева
используя npm install -g recluster-cli && NODE_ENV=production recluster-cli app.js 8
ASP.NET Основной результат стресс-теста приложения
не могу поверить своим глазам! Это не может быть правдой, что в этом базовом тесте asp.net ядро намного быстрее, чем nodejs. Конечно, это не единственная метрика, используемая для измерения производительности между этими двумя веб-технологиями, но мне интересно что я делаю неправильно в узле.js сторона?.
быть профессионалом asp.net разработчик и желающий адаптировать узел.js в личных проектах, это своего рода кое - как я немного обеспокоен производительности. Я думал, узел.js быстрее, чем asp.net ядро (в целом-как видно из различных других тестов) я просто хочу доказать это себе (чтобы побудить себя к адаптации узла.js).
пожалуйста, ответьте в комментарии, если вы хотите, чтобы включить больше фрагментов кода.
обновление: распределение времени .NET Core app
сервер ответ
HTTP/1.1 200 OK
Cache-Control: no-store,no-cache
Date: Fri, 12 May 2017 07:46:56 GMT
Pragma: no-cache
Transfer-Encoding: chunked
Content-Type: text/html; charset=utf-8
Server: Kestrel
2 ответа:
как и многие другие упоминали, сравнение не имеет контекста.
На момент его выпуска, асинхронный подход узла.JS был революционером. С тех пор другие языки и веб-фреймворки принимают подходы, которые они приняли в основном.чтобы понять, что означает разница, вам нужно смоделировать запрос блокировки, который представляет некоторую рабочую нагрузку ввода-вывода, такую как запрос базы данных. В системе thread-per-request это приведет к исчерпанию пула потоков и новых запросов будет помещен в очередь, ожидающую доступного потока.
С неблокирующими фреймворками io этого не происходит.рассмотреть этот узел.сервер JS, который ждет 1 секунду, прежде чем ответить
const server = http.createServer((req, res) => { setTimeout(() => { res.statusCode = 200; res.end(); }, 1000); });
теперь давайте бросим 100 параллельных конценций на него, за 10 С. Таким образом, мы ожидаем около 1000 запросов для завершения.
$ wrk -t100 -c100 -d10s http://localhost:8000 Running 10s test @ http://localhost:8000 100 threads and 100 connections Thread Stats Avg Stdev Max +/- Stdev Latency 1.01s 10.14ms 1.16s 99.57% Req/Sec 0.13 0.34 1.00 86.77% 922 requests in 10.09s, 89.14KB read Requests/sec: 91.34 Transfer/sec: 8.83KB
как вы можете видеть, мы получаем в футбольном поле с 922 завершена.
теперь рассмотрим следующее asp.net код, написанный как бы async/await еще не поддерживались,поэтому мы возвращаемся к узлу.эра запуска js.
app.Run((context) => { Thread.Sleep(1000); context.Response.StatusCode = 200; return Task.CompletedTask; }); $ wrk -t100 -c100 -d10s http://localhost:5000 Running 10s test @ http://localhost:5000 100 threads and 100 connections Thread Stats Avg Stdev Max +/- Stdev Latency 1.08s 74.62ms 1.15s 100.00% Req/Sec 0.00 0.00 0.00 100.00% 62 requests in 10.07s, 5.57KB read Socket errors: connect 0, read 0, write 0, timeout 54 Requests/sec: 6.16 Transfer/sec: 566.51B
62! Здесь мы видим предел пула потоков. Настроив его, мы могли бы получить больше параллельных запросов, но за счет большего количества ресурсов сервера.
для этих рабочих нагрузок, связанных с IO, перемещение, чтобы избежать блокировки потоков обработки, было настолько драматичным.
теперь давайте приведем его к сегодняшнему дню, где это влияние пульсировало через промышленность и позволяло dotnet, чтобы воспользоваться его улучшениями.
app.Run(async (context) => { await Task.Delay(1000); context.Response.StatusCode = 200; }); $ wrk -t100 -c100 -d10s http://localhost:5000 Running 10s test @ http://localhost:5000 100 threads and 100 connections Thread Stats Avg Stdev Max +/- Stdev Latency 1.01s 19.84ms 1.16s 98.26% Req/Sec 0.12 0.32 1.00 88.06% 921 requests in 10.09s, 82.75KB read Requests/sec: 91.28 Transfer/sec: 8.20KB
никаких сюрпризов здесь, мы теперь совпадаем узел.js.
так что же все это значит?
ваши впечатления, что узел.js - это "самый быстрый" выход из эпохи, в которой мы больше не живем. Добавьте к этому, что это никогда не было node/js/v8, которые были "быстрыми", это было то, что они сломали модель потока на запрос. Все остальные уже подтягиваются.
если ваша цель-максимально быстрая обработка одиночных запросов, тогда посмотри на серьезные ориентиры вместо того, чтобы катить свой собственный. Но если вместо этого вы хотите просто что-то, что масштабируется до современных стандартов, тогда перейдите на любой язык, который вам нравится, и убедитесь, что вы не блокируете эти потоки.
отказ от ответственности: весь написанный код и тесты выполняются на стареющем MacBook Air во время сонного воскресного утра. Не стесняйтесь захватить код и попробовать его на Windows или настроить под свои нужды - https://github.com/csainty/nodejs-vs-aspnetcore
узловые структуры, такие как Express и Koa, имеют ужасные накладные расходы. "Сырой" узел работает значительно быстрее.
Я не пробовал, но есть новая структура, которая очень близка к" сырой " производительности узла:https://github.com/aerojs/aero
(см. Тест на этой странице)
обновление: вот некоторые цифры:https://github.com/blitzprog/webserver-benchmarks
Node: 31336.78 31940.29 Aero: 29922.20 27738.14 Restify: 19403.99 19744.61 Express: 19020.79 18937.67 Koa: 16182.02 16631.97 Koala: 5806.04 6111.47 Hapi: 497.56 500.00
Как вы можете видеть, накладные расходы в самый популярный узел.рамки js очень значительны!