node.jsとASP.NET Coreのパフォーマンステストの予期しない結果


177

で書かれた2つの(ちょっと)hello worldプロジェクトで簡単なストレステストをしています そして 。どちらもプロダクションモードで実行されており、ロガーが接続されていません。結果は驚くべきものです!ASP.NETコアは、node.jsアプリが単にビューをレンダリングしているのに対して、追加の作業を行った後でもnode.jsアプリよりも優れています。

アプリ1: http://localhost:3000/nodejs node.js

使用:node.js、ExpressおよびVashレンダリングエンジン。

nodejsアプリ

このエンドポイントのコードは

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 Core、デフォルトのテンプレートターゲティングdnxcore50

ただし、このアプリは、日付が表示されているページをレンダリングするだけではありません。さまざまなランダムテキストの5つの段落を生成します。これにより、理論的には、nodejsアプリよりも少し重くなるはずです。

asp.netコアアプリ

このページをレンダリングするアクションメソッドは次のとおりです

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

ストレステスト結果

Node.jsアプリのストレステスト結果

更新:Gorgi Kosevの提案に従って

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

nodejsテスト2

ASP.NET Coreアプリのストレステスト結果

asp.netコアストレステスト結果

私の目が信じられない!この基本的なテストでは、asp.netコアがnodejsよりもはるかに高速であるとは言えません。もちろん、これはこれら2つのWebテクノロジー間のパフォーマンスを測定するために使用される唯一のメトリックではありませんが、node.js側で何が問題になっているのでしょうか?

プロのasp.net開発者であり、個人プロジェクトでnode.jsを適合させたいと思っているので、これは私を少し先延ばしにしています-パフォーマンスについて少し偏執的だからです。node.jsはasp.netコアよりも高速だと思いました(一般に-他のさまざまなベンチマークで見られるように)自分で証明したいだけです(node.jsの適応を促進するため)。

さらにコードスニペットを含める場合は、コメントで返信してください。

更新: .NET Coreアプリの時間分布

aspnetcoreアプリの時間分布

サーバーの応答

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

52
「node.jsはasp.netコアよりも高速だといつも思っていました」 -なぜそう思うのでしょうか。これをサポートするベンチマークを見たことがありません(node.jsを採用した主な理由は、「使いやすさ」と「開発/反復時間の短縮」
でした

7
@UnholySheepそれは私が聞いたものすべてです、私はそれがまた「使いやすい」そして「開発がより速い」とも聞きました。私はどんなテクノロジーについても自慢していませんが、これは私が気付いたパターンです。
未定義

3
ここでの質問は何ですか?もっともらしい場合:はい。techempower.com/benchmarks/… ....また、ツールチェーンを更新するDnxcore50が少なくとも1〜2年古くなっています。
トーマス

2
クラスタモジュールNodeJsを使用する@Tonyは、複数のワーカーを生成し、単一のプロセスでリッスンしているメインプロセスの負荷を共有します。異なるポートで複数のアプリケーションをセットアップする必要がなくなるだけです。また、nodeJsがクラスターモードで実行されている場合、IISのdiffポートで同じ数のAsp.Net WebApplicationsが実行されており、ロードバランサーを介してそれらの間で負荷を共有している必要があります。
Vipresh

36
Node.jsは多くの点で優れていますが、リクエストごとの実速度はその1つではありません。それが得意とするのは、ノードが新しくて光沢のあるときに大したことであった非ブロッキングイベントループの事柄のため、I / O操作のブローカーであるということです。もちろん、それ以降、他の言語やフレームワークが追いついてきたので、.NETにはTask Parallel Libraryと非同期I / Oおよびasync / awaitがあります。Nodeが優れていないのは、シングルスレッドのJavaScriptであるため、ページレンダリングのようなCPUにバインドされた操作です。
マークレンタル

回答:


188

他の多くの人がほのめかしたように、比較には文脈がありません。
リリース時のnode.jsの非同期アプローチは革新的でした。それ以来、他の言語やWebフレームワークが主流になったアプローチを採用しています。

違いが何を意味するかを理解するには、データベースリクエストなどのIOワークロードを表すブロッキングリクエストをシミュレートする必要があります。要求ごとのスレッドシステムでは、これによりスレッドプールが使い果たされ、新しい要求が使用可能なスレッドを待機するキューに入れられます。
非ブロッキングioフレームワークでは、これは起こりません。

応答する前に1秒間待機するこのnode.jsサーバーを検討してください。

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

次に、10秒間、100の同時接続をスローします。したがって、約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が完了した状態で球場に入ります。

ここで、async / awaitがまだサポートされていないかのように書かれた次のasp.netコードを検討します。そのため、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!ここでは、スレッドプールの制限を確認します。それを調整することで、より多くの同時要求を発生させることができますが、サーバーリソースが増加します。

これらの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

ここで驚くことはありません。node.jsに一致します。

では、これはどういう意味ですか?

node.jsが「最速」であるという印象は、私たちがもう住んでいない時代から来ています。それに加えて、「高速」であったのはnode / js / v8ではなく、リクエストごとのスレッドが壊れたということです。モデル。他の誰もが追いついてきた。

目標が単一リクエストの最速の処理である場合は、深刻なベンチマークを見てください。独自にロールするのではなくを確認してください。しかし、代わりに必要なものが単純に現代の標準に対応するものである場合は、好きな言語を選び、それらのスレッドをブロックしていないことを確認してください。

免責事項:すべてのコードが記述され、テストは、老朽化し​​たMacBook Airで眠い日曜日の朝に実行されます。コードを入手してWindowsで試すか、ニーズに合わせて調整してください-https ://github.com/csainty/nodejs-vs-aspnetcore


35
NodeJは一意ではありませんでした。nodejsが導入される前に、要求ごとのスレッドモデルもAsp.Netに存在していました。I/ Oを実行するすべてのメソッドには、フレームワークによって提供される2つのバージョンの同期および非同期があり、ASYNCメソッドはキーワード「Async」で終了します。例えば。methodNameAsync
Vipresh

例として。Uは、2008年まで遡るDB操作に関連するこの記事を参照できます。codedigest.com
Articles / ADO /

4
「彼らが主流にしたアプローチ」-ユニークなものはほとんどなく、彼らは問題をはるかに広い聴衆の前に置きます。利用可能なアプローチを用意することと、それを核となる原則として取り入れることは、2つの非常に異なることです。
Chris Sainty

4
ここで最良の答えです。限目。
Narvalex 2017

3
@LeeBrindley同意しない、これは特定のハードウェアの最大スループットを実証しようとしているのではなく、ブロッキングと非ブロッキングの違いを示している。生のスループット比較が必要な場合は、techempowerにリンクします。
Chris Sainty

14

ExpressやKoaなどのノードフレームワークには、ひどいオーバーヘッドがあります。「生」ノードは大幅に高速です。

私は試していませんが、「Raw」ノードのパフォーマンスに非常に近い新しいフレームワークがあります。 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

ご覧のとおり、最も一般的なnode.jsフレームワークのオーバーヘッドは非常に重要です。


5
何の数字ですか?高いほど良いですか?
Iamisti 2018
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.