简体   繁体   English

node.js与ASP.NET核心性能测试的意外结果

[英]Unexpected outcome of node.js vs ASP.NET Core performance test

I am doing a quick stress test on two (kinda) hello world projects written in and . 我正在用编写的两个(有点)hello world项目进行快速压力测试。 Both of them are running in production mode and without a logger attached to them. 它们都在生产模式下运行,并且没有连接记录器。 The result is astonishing! 结果令人惊讶! ASP.NET core is outperforming node.js app even after doing some extra work whereas the node.js app is just rendering a view. 即使在做了一些额外的工作之后,ASP.NET核心也优于node.js应用程序,而node.js应用程序只是渲染视图。

App 1: http://localhost:3000/nodejs node.js 应用1: http://localhost:3000/nodejs node.js

Using : node.js, express and vash rendering engine. 使用 :node.js,express和vash渲染引擎。

nodejs app

The code in this endpoint is 此端点中的代码是

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

As you can see, it does nothing apart from sending current date via the time variable to the view. 正如您所看到的,除了通过time变量将当前日期发送到视图之外,它什么也没做。

App 2: http://localhost:5000/aspnet-core asp.net core 应用2: http://localhost:5000/aspnet-core asp.net core

Using : ASP.NET Core, default template targeting dnxcore50 使用 :ASP.NET Core,默认模板定位dnxcore50

However this app does something other than just rendering a page with a date on it. 然而,这个应用程序不仅仅是渲染一个带有日期的页面。 It generates 5 paragraphs of various random texts. 它生成5段各种随机文本。 This should theoretically make this little bit heavier than the nodejs app. 从理论上讲,这应该比nodejs app重一点。

asp.net核心应用程序

Here is the action method that render this page 这是呈现此页面的操作方法

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

Stress test result 压力测试结果

Node.js App stress test result Node.js App压力测试结果

Update: Following suggestion by Gorgi Kosev 更新: 遵循Gorgi Kosev的建议

Using npm install -g recluster-cli && NODE_ENV=production recluster-cli app.js 8 使用npm install -g recluster-cli && NODE_ENV=production recluster-cli app.js 8

nodejs测试2

ASP.NET Core App stress test result ASP.NET Core App压力测试结果

asp.net核心压力测试结果

Can't believe my eyes! 不敢相信自己的眼睛! It can't be true that in this basic test asp.net core is way faster than nodejs. 在这个基本测试中,asp.net核心比nodejs更快,这是不正确的。 Off course this is not the only metric used to measure performance between these two web technologies, but I am wondering what am I doing wrong in the node.js side? 当然,这不是衡量这两种网络技术之间性能的唯一指标,但我想知道我在node.js方面做错了什么? .

Being a professional asp.net developer and wishing to adapt node.js in personal projects, this is kind of putting me off - as I'm a little paranoid about performance. 作为一个专业的asp.net开发人员,并希望在个人项目中适应node.js,这有点让我失望 - 因为我对性能有点偏执。 I thought node.js is faster than asp.net core (in general - as seen in various other benchmarks) I just want to prove it to myself (to encourage myself in adapting node.js). 我认为node.js比asp.net核心更快(一般来说 - 如各种其他基准测试中所见)我只是想向自己证明这一点(鼓励自己适应node.js)。

Please reply in comment if you want me to include more code snippets. 如果您希望我包含更多代码段,请在评论中回复。

Update: Time distribution of .NET Core app 更新: .NET Core应用程序的时间分配

aspnetcore应用程序时间分配

Server response 服务器响应

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

As many others have alluded, the comparison lacks context. 正如许多其他人所暗示的那样,这种比较缺乏背景。
At the time of its release, the async approach of node.js was revolutionary. 在发布时,node.js的异步方法是革命性的。 Since then other languages and web frameworks have been adopting the approaches they took mainstream. 从那以后,其他语言和网络框架一直采用他们采用主流的方法。

To understand what the difference meant, you need to simulate a blocking request that represents some IO workload, such as a database request. 要了解差异的含义,您需要模拟代表某些IO工作负载的阻塞请求,例如数据库请求。 In a thread-per-request system, this will exhaust the threadpool and new requests will be put in to a queue waiting for an available thread. 在每个请求线程系统中,这将耗尽线程池,并且新请求将被放入等待可用线程的队列中。
With non-blocking-io frameworks this does not happen. 使用非阻塞io框架,这不会发生。

Consider this node.js server that waits 1 second before responding 考虑这个node.js服务器在响应之前等待1秒

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

Now let's throw 100 concurrent conenctions at it, for 10s. 现在让我们在它上面投入100个并发意外,持续10秒。 So we expect about 1000 requests to complete. 所以我们希望完成大约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

As you can see we get in the ballpark with 922 completed. 正如你所看到的那样,我们完成了922球。

Now consider the following asp.net code, written as though async/await were not supported yet, therefore dating us back to the node.js launch era. 现在考虑下面的asp.net代码,好像async / await还不支持,因此我们回到node.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! 62! Here we see the limit of the threadpool. 在这里,我们看到了线程池的限制。 By tuning it up we could get more concurrent requests happening, but at the cost of more server resources. 通过调整它,我们可以获得更多的并发请求,但代价是更多的服务器资源。

For these IO-bound workloads, the move to avoid blocking the processing threads was that dramatic. 对于这些IO绑定工作负载,避免阻塞处理线程的举动非常引人注目。

Now let's bring it to today, where that influence has rippled through the industry and allow dotnet to take advantage of its improvements. 现在让我们把它带到今天,这种影响已经在整个行业中起作用,并允许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

No surprises here, we now match node.js. 这里没有惊喜,我们现在匹配node.js.

So what does all this mean? 那么,这意味着什么?

Your impressions that node.js is the "fastest" come from an era we are no longer living in. Add to that it was never node/js/v8 that were "fast", it was that they broke the thread-per-request model. 你对node.js是“最快的”的印象来自我们不再生活的时代。再加上它从来就不是node / js / v8那么“快”,而是他们打破了每个请求的线程模型。 Everyone else has been catching up. 其他人都在追赶。

If your goal is the fastest possible processing of single requests, then look at the serious benchmarks instead of rolling your own. 如果您的目标是尽可能快地处理单个请求,那么请查看严格的基准测试,而不是自行编写。 But if instead what you want is simply something that scales to modern standards, then go for whichever language you like and make sure you are not blocking those threads. 但是,如果您想要的只是符合现代标准的东西,那么请选择您喜欢的任何语言,并确保您不会阻止这些线程。

Disclaimer: All code written, and tests run, on an ageing MacBook Air during a sleepy Sunday morning. 免责声明:在昏昏欲睡的周日早晨,所有代码都在老化的MacBook Air上编写和测试。 Feel free to grab the code and try it on Windows or tweak to your needs - https://github.com/csainty/nodejs-vs-aspnetcore 随意获取代码并在Windows上试用或调整以满足您的需求 - https://github.com/csainty/nodejs-vs-aspnetcore

Node Frameworks like Express and Koa have a terrible overhead. 像Express和Koa这样的节点框架具有可怕的开销。 "Raw" Node is significantly faster. “原始”节点明显更快。

I haven't tried it, but there's a newer framework that gets very close to "Raw" Node performance: https://github.com/aerojs/aero 我没有尝试过,但有一个更新的框架非常接近“原始”节点性能: https//github.com/aerojs/aero

(see benchmark on that page) (参见该页面的基准)

update: Here are some figures: https://github.com/blitzprog/webserver-benchmarks 更新:以下是一些数字: 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

As you can see, the overheads in the most popular node.js frameworks are VERY significant! 如您所见,最流行的node.js框架中的开销非常重要!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM