[解決済み】node.js vs ASP.NET Core パフォーマンステストの予期せぬ結果
質問
で書かれた2つの(一種の)hello worldプロジェクトで簡単なストレステストを行っています。 node.js と 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アプリのストレステスト結果
更新情報 Gorgi Kosev氏の提案に従う。
使用方法
npm install -g recluster-cli && NODE_ENV=production recluster-cli app.js 8
ASP.NET Coreアプリストレステスト結果
自分の目を疑うような光景です。この基本的なテストでは、asp.net coreがnodejsよりずっと速いというのはありえないことです。もちろん、この2つのウェブテクノロジーのパフォーマンスを測定するために使用される唯一の指標ではありませんが、私は不思議に思っています。 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
解決方法は?
他の多くの人が言及しているように、この比較は文脈を欠いています。
リリース当時、node.jsの非同期アプローチは画期的でした。それ以来、他の言語やウェブフレームワークは、彼らが主流としたアプローチを採用しています。
この違いが何を意味するのかを理解するためには、データベースへのリクエストなど、何らかの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個を完成させ、大台に乗せることができました。
次の 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! ここで、スレッドプールの限界を見ることができます。これをチューニングすることで、より多くの同時リクエストを発生させることができますが、より多くのサーバーリソースを犠牲にしています。
これらの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
関連
-
[解決済み】Ajax処理で「無効なJSONプリミティブ」と表示される件
-
[解決済み】HRESULTからの例外:0x800A03ECエラー
-
[解決済み】Moqを使用してメソッド呼び出しを検証する
-
[解決済み】名前 'ViewBag' が現在のコンテキストに存在しない - Visual Studio 2015
-
[解決済み] ASP.NET CoreでカスタムのAuthorizeAttributeを作成する方法は?
-
[解決済み] Node.js - SyntaxError: 予期しないトークンのインポート
-
[解決済み] ConfigureServices内からASP.NET Core DIでインスタンスを解決する
-
[解決済み] ASP.NET Core Web APIの例外処理
-
[解決済み] ASP.NET CoreでAutomapperを設定する方法
-
[解決済み】ASP.NET CoreでCORSを有効にする方法
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】エラー。「戻り値を変更できません」 C#
-
[解決済み] メンバー '<メンバー名>' にインスタンス参照でアクセスできない
-
[解決済み] 保護レベルによりアクセス不能になりました。
-
[解決済み】Unity 「関連するスクリプトを読み込むことができません」「Win32Exception: システムは指定されたファイルを見つけることができません"
-
[解決済み】"指定されたパスのフォーマットはサポートされていません。"
-
[解決済み】C#のequal to演算子でtextとvarcharのデータ型は互換性がない
-
[解決済み] ...基礎となる接続は閉じられました。予期しないエラーが受信で発生しました
-
[解決済み】ユーザー設定値を別のユーザー設定値で設定する
-
[解決済み】名前 'ViewBag' が現在のコンテキストに存在しない - Visual Studio 2015
-
[解決済み] Node.jsを使うタイミングをどう判断するか?