私は2つの(ちょっと)Hello Worldプロジェクトで簡単なストレステストを行っています。ノードそしてasp.net コアどちらもプロダクション モードで実行されており、ロガーは接続されていません。結果は驚くべきものでした。ASP.NET Core は、追加の作業を行った後でも node.js アプリよりもパフォーマンスが優れていますが、node.js アプリはビューをレンダリングするだけです。
アプリ1:http://localhost:3000/nodejs
node.js
使用: node.js、express、vash レンダリング エンジン。
このエンドポイントのコードは
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 アプリよりも少し重くなるはずです。
このページをレンダリングするアクションメソッドは次のとおりです
[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 アプリのストレステスト結果
アップデート:ゴルギ・コセフの提案に従って
使用npm install -g recluster-cli && NODE_ENV=production recluster-cli app.js 8
ASP.NET Core アプリのストレス テスト結果
信じられない!この基本的なテストでasp.net coreがnodejsよりはるかに速いというのは本当ではない。もちろん、これはこれら2つのWebテクノロジーのパフォーマンスを測定するために使用される唯一の指標ではありませんが、私は疑問に思っています。node.js 側で何が間違っているのでしょうか?。
私はプロの asp.net 開発者であり、個人のプロジェクトに node.js を採用したいと考えていますが、パフォーマンスについては少し心配なので、これは私にとっては気が進みません。私は、node.js は asp.net core よりも高速だと思っていました (一般的に、他のさまざまなベンチマークで見られるように)。私はただそれを自分自身に証明したいだけです (node.js を採用する勇気づけるため)。
さらにコード スニペットを追加して欲しい場合は、コメントで返信してください。
アップデート: .NET Core アプリの時間分布
サーバー応答
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
ベストアンサー1
多くの人がほのめかしているように、この比較には文脈が欠けています。
リリース当時、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 がまだサポートされていなかったかのように記述された、つまり node.js のリリース時代にまで遡る次の asp.net コードを検討してください。
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