Resultado inesperado del nodo.js vs ASP.NET Prueba de rendimiento del núcleo


Estoy haciendo una prueba de estrés rápida en dos (un poco) proyectos de hello world escritos en el nodo .js y asp.net-core. Ambos se ejecutan en modo de producción y sin un registrador conectado a ellos. El resultado es sorprendente! ASP.NET el núcleo está superando al nodo.aplicación js incluso después de hacer un poco de trabajo adicional, mientras que el nodo.la aplicación js solo está renderizando una vista.

Aplicación 1: http://localhost:3000/nodejs node.js

Usando : nodo.renderizado js, express y vash motor.

aplicación nodejs

El código en este punto final es

router.get('/', function(req, res, next) {
  var vm = {
    title: 'Express',
    time: new Date()
  }
  res.render('index', vm);
});

Como puede ver, no hace nada aparte de enviar la fecha actual a través de la variable time a la vista.

Aplicación 2: http://localhost:5000/aspnet-core asp.net core

Usando: ASP.NET Núcleo, segmentación por plantilla predeterminada dnxcore50

Sin embargo, esta aplicación hace algo más que representar una página con una fecha en ella. Genera 5 párrafos de varios textos aleatorios. Esto debería teóricamente hacer esto un poco más pesado que la aplicación nodejs.

asp.net principal de la aplicación

Aquí está el método de acción que renderiza esta página

[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();
}

Resultado de la prueba de resistencia

Nodo.js App stress test result

Actualización: Siguiendo la sugerencia de Gorgi Kosev

Usando npm install -g recluster-cli && NODE_ENV=production recluster-cli app.js 8

prueba nodejs 2

ASP.NET Core App stress test result

asp.net resultado de la prueba de resistencia del núcleo

¡No puedo creer lo que veo! No puede ser cierto que en este básico ensayo asp.net core es mucho más rápido que nodejs. Por supuesto, esta no es la única métrica utilizada para medir el rendimiento entre estas dos tecnologías web, pero me pregunto qué estoy haciendo mal en el nodo.js lado?.

Ser un profesional asp.net desarrollador y deseando adaptar nodo.js en proyectos personales, esto me está desanimando, ya que estoy un poco paranoico con el rendimiento. Pensé nodo.js es más rápido que asp.net core (in general-as seen in various other benchmarks) Solo quiero demostrármelo a mí mismo (para animarme a adaptar node.js).

Por favor, responda en un comentario si desea que incluya más fragmentos de código.

Actualización: Distribución de tiempo de la aplicación. NET Core

distribución de tiempo de la aplicación aspnetcore

Respuesta del Servidor

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
Author: user3071284, 2017-05-11

2 answers

Como muchos otros han aludido, la comparación carece de contexto.
En el momento de su lanzamiento, el enfoque asincrónico de node.js fue revolucionario. Desde entonces, otros lenguajes y marcos web han estado adoptando los enfoques que se generalizaron.

Para entender lo que significaba la diferencia, debe simular una solicitud de bloqueo que represente alguna carga de trabajo de E / s, como una solicitud de base de datos. En un sistema de subproceso por solicitud, esto agotará el threadpool y se pondrán nuevas solicitudes en una cola esperando un hilo disponible.
Con marcos de e / s sin bloqueo, esto no sucede.

Considere este nodo.servidor js que espera 1 segundo antes de responder

const server = http.createServer((req, res) => {
  setTimeout(() => {
    res.statusCode = 200;
    res.end();
  }, 1000);
});

Ahora vamos a lanzar 100 conexiones simultáneas, para 10s. Así que esperamos que se completen alrededor de 1000 solicitudes.

$ 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

Como pueden ver, llegamos al estadio con 922 completados.

Ahora considere lo siguiente asp.net código, escrito como si async / await no estuviera soportado todavía, por lo tanto saliendo con nosotros hasta el nodo.era de lanzamiento de 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! Aquí vemos el límite de la threadpool. Al ajustarlo, podríamos obtener más solicitudes simultáneas, pero a costa de más recursos del servidor.

Para estas cargas de trabajo vinculadas a IO, el movimiento para evitar bloquear los subprocesos de procesamiento fue tan dramático.

Ahora vamos a llevarlo a la actualidad, donde esa influencia se ha ondulado a través de la industria y permitir dotnet para aprovechar sus mejoras.

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

No sorpresas aquí, ahora coincidimos nodo.js.

Entonces, ¿qué significa todo esto?

Tus impresiones de ese nodo.js es el" más rápido " que viene de una época en la que ya no vivimos. Añadir a que nunca fue node / js / v8 que fueron "rápidos", fue que rompieron el modelo de hilo por solicitud. Todos los demás se han puesto al día.

Si su objetivo es el procesamiento más rápido posible de solicitudes individuales, entonces mire los puntos de referencia serios en lugar de rodar los suyos propios. Pero si en cambio lo que quieres es simplemente algo que escala a los estándares modernos, luego elige el idioma que te guste y asegúrate de no bloquear esos hilos.

Descargo de responsabilidad: Todo el código escrito, y las pruebas se ejecutan, en un MacBook Air envejecido durante una mañana de domingo soñoliento. Siéntase libre de agarrar el código y probarlo en Windows o ajustar a sus necesidades - https://github.com/csainty/nodejs-vs-aspnetcore

 116
Author: Chris Sainty,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-21 06:04:45

Los frameworks de nodos como Express y Koa tienen una sobrecarga terrible. El nodo " Raw " es significativamente más rápido.

No lo he probado, pero hay un marco más nuevo que se acerca mucho al rendimiento del nodo" Raw": https://github.com/aerojs/aero

(ver benchmark en esa página)

Actualización: Aquí hay algunas cifras: 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

Como puede ver, los gastos generales en el nodo más popular.los marcos de js son MUY ¡significativo!

 8
Author: smorgs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-13 06:26:41