Hasil yang tidak terduga dari node.js vs tes kinerja ASP.NET Core

177

Saya melakukan tes stres cepat pada dua (agak) halo proyek dunia yang ditulis dan . Keduanya berjalan dalam mode produksi dan tanpa logger yang menyertainya. Hasilnya mencengangkan! Inti ASP.NET mengungguli aplikasi node.js bahkan setelah melakukan beberapa pekerjaan tambahan sedangkan aplikasi node.js hanya menampilkan tampilan.

Aplikasi 1: http://localhost:3000/nodejs node.js

Menggunakan : node.js, mesin rendering ekspres dan vash.

aplikasi simpuljs

Kode di titik akhir ini adalah

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

Seperti yang Anda lihat, itu tidak melakukan apa-apa selain mengirim tanggal saat ini melalui timevariabel ke tampilan.

Aplikasi 2: http://localhost:5000/aspnet-core asp.net core

Menggunakan : ASP.NET Core, penargetan templat defaultdnxcore50

Namun aplikasi ini melakukan sesuatu selain dari hanya merender halaman dengan tanggal di atasnya. Ini menghasilkan 5 paragraf dari berbagai teks acak. Ini secara teoritis harus membuat ini sedikit lebih berat daripada aplikasi nodejs.

aplikasi inti asp.net

Berikut adalah metode tindakan yang merender halaman ini

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

Hasil tes stres

Hasil stress test Node.js App

Pembaruan: Mengikuti saran dari Gorgi Kosev

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

tes simpuljs 2

Hasil tes stres ASP.NET Core App

asp.net hasil tes stres inti

Tidak bisa mempercayai mataku! Tidak mungkin benar bahwa dalam tes dasar ini inti asp.net jauh lebih cepat daripada nodejs. Tentunya ini bukan satu-satunya metrik yang digunakan untuk mengukur kinerja antara dua teknologi web ini, tetapi saya bertanya-tanya apa yang saya lakukan salah di sisi node.js? .

Menjadi pengembang asp.net profesional dan ingin mengadaptasi node.js dalam proyek-proyek pribadi, ini agak membuat saya kecewa - karena saya sedikit paranoid tentang kinerja. Saya pikir node.js lebih cepat dari inti asp.net (secara umum - seperti yang terlihat di berbagai tolok ukur lainnya) Saya hanya ingin membuktikannya kepada diri saya sendiri (untuk mendorong diri saya dalam mengadaptasi node.js).

Harap balas komentar jika Anda ingin saya memasukkan lebih banyak cuplikan kode.

Pembaruan: Distribusi waktu aplikasi .NET Core

distribusi waktu aplikasi aspnetcore

Respons server

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
tidak terdefinisi
sumber
52
"Saya selalu berpikir node.js lebih cepat dari inti asp.net" - Saya ingin tahu mengapa Anda berpikir begitu? Saya belum melihat adanya tolok ukur yang akan mendukung ini (alasan utama yang saya dengar untuk mengadopsi node.js adalah "kemudahan penggunaan" dan "waktu pengembangan / iterasi yang lebih cepat")
UnholySheep
7
@UnholySheep Ini semua yang saya dengar sobat, saya juga dengar itu "mudah digunakan" dan "lebih cepat berkembang" juga, umumnya dari orang yang pernah menggunakan ASP.NET, terutama di VisualStudio. Saya tidak membual tentang teknologi apa pun - tetapi ini adalah pola yang saya perhatikan.
tidak ditentukan
3
Apa pertanyaannya di sini? Jika itu masuk akal: Ya itu. techempower.com/benchmarks/… .... Juga perbarui toolchain Anda Dnxcore50 sudah usang setidaknya untuk satu atau dua tahun.
Thomas
2
@Tony menggunakan modul cluster NodeJs memunculkan beberapa pekerja melakukan dan berbagi beban proses utama yang mendengarkan pada proses tunggal. Itu hanya menghindari harus mengatur beberapa aplikasi pada port yang berbeda. Juga jika nodeJs berjalan dalam mode cluster maka harus ada jumlah yang sama dari Aplikasi Web Asp.Net berjalan di IIS pada port yang berbeda dan berbagi beban di antara mereka melalui beberapa penyeimbang beban, maka itu akan menjadi perbandingan yang tepat.
Vipresh
36
Node.js sangat bagus untuk banyak hal, tetapi kecepatan mentah per permintaan bukan salah satunya. Yang unggul di sini adalah menjadi pialang untuk operasi I / O, karena hal-loop acara non-blocking, yang, ketika Node baru dan mengkilap, adalah masalah besar. Tentu saja, sejak saat itu bahasa dan kerangka kerja lain telah menyusul, jadi di .NET kami memiliki Pustaka Paralel Tugas dan I / O dan asinkron / async / menunggu. Yang tidak disukai Node adalah operasi yang terikat CPU seperti rendering halaman, karena ini adalah JavaScript single-threaded.
Mark Rendle

Jawaban:

188

Seperti yang telah disinggung oleh banyak orang lain, perbandingan itu tidak memiliki konteks.
Pada saat dirilis, pendekatan async dari node.js adalah revolusioner. Sejak itu bahasa lain dan kerangka kerja web telah mengadopsi pendekatan yang mereka ambil arus utama.

Untuk memahami apa perbedaannya, Anda perlu mensimulasikan permintaan pemblokiran yang mewakili beberapa beban kerja IO, seperti permintaan basis data. Di sistem utas per permintaan, ini akan menghabiskan threadpool dan permintaan baru akan dimasukkan ke antrian menunggu utas tersedia.
Dengan kerangka kerja non-blocking-io ini tidak terjadi.

Pertimbangkan server node.js ini yang menunggu 1 detik sebelum merespons

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

Sekarang mari kita lemparkan 100 konkurensi konkuren untuk 10s. Jadi kami berharap sekitar 1000 permintaan selesai.

$ 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

Seperti yang dapat Anda lihat, kami tiba di stadion baseball dengan 922 selesai.

Sekarang perhatikan kode asp.net berikut, ditulis seolah-olah async / menunggu belum didukung, oleh karena itu dating kembali ke era peluncuran 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! Di sini kita melihat batas threadpool. Dengan menyetelnya, kita bisa mendapatkan lebih banyak permintaan bersamaan, tetapi dengan biaya lebih banyak sumber daya server.

Untuk beban kerja yang terikat IO ini, langkah untuk menghindari pemblokiran thread pemrosesan sangat dramatis.

Sekarang mari kita bawa ke hari ini, di mana pengaruh itu telah beriak melalui industri dan memungkinkan dotnet untuk mengambil keuntungan dari peningkatannya.

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

Tidak ada kejutan di sini, kami sekarang mencocokkan node.js.

Jadi apa artinya semua ini?

Kesan Anda bahwa node.js adalah "tercepat" berasal dari era kita tidak lagi hidup. Tambahkan ke bahwa itu tidak pernah node / js / v8 yang "cepat", itu adalah bahwa mereka melanggar thread-per-permintaan model. Semua orang sudah menyusul.

Jika tujuan Anda adalah pemrosesan permintaan tunggal yang paling cepat, maka lihatlah tolok ukur yang serius daripada menggulirkan permintaan Anda sendiri. Tetapi jika sebaliknya yang Anda inginkan hanyalah sesuatu yang memenuhi standar modern, maka pilih bahasa apa pun yang Anda suka dan pastikan Anda tidak memblokir utas tersebut.

Penafian: Semua kode ditulis, dan tes dijalankan, pada MacBook Air yang menua selama Minggu pagi yang mengantuk. Jangan ragu untuk mengambil kode dan mencobanya di Windows atau sesuaikan dengan kebutuhan Anda - https://github.com/csainty/nodejs-vs-aspnetcore

Chris Sainty
sumber
35
NodeJs tidak pernah unik, model Thread per request juga ada di Asp.Net sebelum nodejs diperkenalkan. Semua metode yang I / O punya 2 versi sinkron dan Asynchronous disediakan oleh Framework, metode ASYNC mereka berakhir dengan kata kunci "Async" untuk misalnya. methodNameAsync
Vipresh
Sebagai contoh. Anda dapat merujuk ke artikel ini terkait dengan operasi DB yang berasal dari 2008 codedigest.com/Articles/ADO/…
Vipresh
4
"pendekatan yang mereka ambil arus utama" - beberapa hal unik, mereka menempatkan masalah ini di depan khalayak yang lebih luas. Memiliki pendekatan yang tersedia, dan menjadikannya sebagai prinsip inti adalah dua hal yang sangat berbeda.
Chris Sainty
4
Jawaban terbaik di sini. Titik.
Narvalex
3
@ LeeBrindley Saya tidak setuju, ini tidak mencoba untuk menunjukkan throughput maksimum dari perangkat keras yang diberikan, itu menunjukkan perbedaan antara memblokir dan non-memblokir. Jika Anda ingin perbandingan throughput mentah, saya menautkan ke teknologi.
Chris Sainty
14

Kerangka Node seperti Express dan Koa memiliki overhead yang buruk. "Raw" Node secara signifikan lebih cepat.

Saya belum mencobanya, tetapi ada kerangka kerja yang lebih baru yang mendekati kinerja "Raw" Node: https://github.com/aerojs/aero

(lihat patokan di halaman itu)

pembaruan: Berikut adalah beberapa angka: 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

Seperti yang Anda lihat, overhead dalam kerangka node.js paling populer SANGAT signifikan!

smorgs
sumber
5
untuk apa angka-angka itu? Lebih tinggi lebih baik?
Iamisti