Saya percaya komunitas Erlang tidak iri pada Node.js karena tidak memblokir I / O secara asli dan memiliki cara untuk mengukur penyebaran dengan mudah ke lebih dari satu prosesor (sesuatu yang bahkan tidak ada di Node.js). Lebih detail di http://journal.dedasys.com/2010/04/29/erlang-vs-node-js dan Node.js atau Erlang
Bagaimana dengan Haskell? Bisakah Haskell memberikan beberapa manfaat dari Node.js, yaitu solusi bersih untuk menghindari pemblokiran I / O tanpa meminta bantuan pemrograman multi-thread?
Ada banyak hal yang menarik dengan Node.js
- Acara: Tanpa manipulasi utas, programmer hanya menyediakan panggilan balik (seperti pada kerangka kerja Snap)
- Panggilan balik dijamin dijalankan dalam utas tunggal: tidak ada kondisi balapan yang mungkin.
- API ramah-UNIX yang bagus dan sederhana. Bonus: Dukungan HTTP luar biasa. DNS juga tersedia.
- Setiap I / O secara default tidak sinkron. Ini membuatnya lebih mudah untuk menghindari kunci. Namun, terlalu banyak pemrosesan CPU dalam panggilan balik akan berdampak pada koneksi lain (dalam hal ini, tugas harus dipecah menjadi sub-tugas yang lebih kecil dan dijadwalkan ulang).
- Bahasa yang sama untuk sisi klien dan sisi server. (Saya tidak melihat terlalu banyak nilai dalam yang satu ini. Namun, jQuery dan Node.js berbagi model acara pemrograman tetapi sisanya sangat berbeda. Saya hanya tidak bisa melihat bagaimana berbagi kode antara sisi server dan sisi klien bisa berguna dalam latihan.)
- Semua ini dikemas dalam satu produk.
Jawaban:
Ok, jadi setelah menyaksikan sedikit presentasi node.js yang ditunjukkan @gawi kepada saya, saya bisa mengatakan sedikit lebih banyak tentang bagaimana Haskell dibandingkan dengan node.js. Dalam presentasi tersebut, Ryan menjelaskan beberapa manfaat dari Green Threads, tetapi kemudian mengatakan bahwa ia tidak menemukan kurangnya abstraksi thread menjadi kerugian. Saya tidak setuju dengan posisinya, terutama dalam konteks Haskell: Saya pikir abstraksi yang disediakan thread sangat penting untuk membuat kode server lebih mudah untuk mendapatkan yang benar, dan lebih kuat. Khususnya:
menggunakan satu utas per koneksi memungkinkan Anda menulis kode yang mengekspresikan komunikasi dengan satu klien, alih-alih menulis kode yang berhubungan dengan semua klien secara bersamaan. Pikirkan seperti ini: server yang menangani banyak klien dengan utas terlihat hampir sama dengan yang menangani satu klien; perbedaan utama adalah ada suatu
fork
tempat di bekas. Jika protokol yang Anda implementasikan sangat rumit, mengelola mesin negara untuk banyak klien secara bersamaan menjadi cukup rumit, sedangkan utas memungkinkan Anda membuat skrip komunikasi dengan satu klien saja. Kode lebih mudah untuk diperbaiki, dan lebih mudah dipahami dan dipelihara.panggilan balik pada utas OS tunggal adalah multitasking kooperatif, tidak seperti multitasking preemptive, yang adalah apa yang Anda dapatkan dengan utas. Kerugian utama dengan multitasking kooperatif adalah bahwa programmer bertanggung jawab untuk memastikan bahwa tidak ada kelaparan. Kehilangan modularitas: membuat kesalahan di satu tempat, dan itu dapat mengacaukan seluruh sistem. Ini benar-benar sesuatu yang tidak ingin Anda khawatirkan, dan preemption adalah solusi sederhana. Selain itu, komunikasi antara panggilan balik tidak dimungkinkan (itu akan menemui jalan buntu).
concurrency tidak sulit di Haskell, karena sebagian besar kode murni dan aman untuk konstruksi. Ada primitif komunikasi sederhana. Jauh lebih sulit menembak diri sendiri dengan konkurensi di Haskell daripada dalam bahasa dengan efek samping yang tidak terbatas.
sumber
Ya, sebenarnya acara dan utas disatukan di Haskell.
Thread sebenarnya diimplementasikan dalam hal peristiwa , dan dijalankan di beberapa inti, dengan migrasi thread yang mulus, dengan kinerja yang terdokumentasi, dan aplikasi.
Misalnya untuk
Koleksi serentak nbody di 32 core
Di Haskell Anda memiliki kedua acara dan utas, dan seperti semua acara di bawah tenda.
Baca makalah yang menjelaskan implementasi.
sumber
Pertama, saya tidak berpendapat bahwa node.js melakukan hal yang benar untuk mengekspos semua panggilan balik itu. Anda akhirnya menulis program Anda dalam CPS (kelanjutan lewat gaya) dan saya pikir itu harus menjadi tugas kompiler untuk melakukan transformasi itu.
Jadi dengan mengingat hal ini, Anda dapat menulis menggunakan gaya asinkron jika Anda menginginkannya, tetapi dengan melakukannya Anda tidak akan menulis dengan gaya sinkron yang efisien, dengan satu utas per permintaan. Haskell sangat efisien dalam kode sinkron, terutama jika dibandingkan dengan bahasa lain. Itu semua kejadian di bawahnya.
Anda masih bisa memiliki kondisi balapan di node.js, tetapi ini lebih sulit.
Setiap permintaan ada di utasnya sendiri. Ketika Anda menulis kode yang harus berkomunikasi dengan utas lain, sangat mudah untuk membuatnya utas karena terima kasih kepada concurrency concurrency haskell.
Lihatlah hackage dan lihat sendiri.
Anda tidak memiliki masalah seperti itu, ghc akan mendistribusikan pekerjaan Anda di antara utas OS nyata.
Haskell tidak mungkin menang di sini ... kan? Pikirkan lagi, http://www.haskell.org/haskellwiki/Haskell_in_web_browser .
Unduh ghc, jalankan komplotan rahasia. Ada paket untuk setiap kebutuhan.
sumber
Saya pribadi melihat Node.js dan pemrograman dengan callback sebagai level rendah yang tidak perlu dan sedikit hal yang tidak wajar. Mengapa memprogram dengan callback ketika runtime yang bagus seperti yang ditemukan di GHC dapat menangani callback untuk Anda dan melakukannya dengan cukup efisien?
Sementara itu, runtime GHC telah meningkat pesat: sekarang fitur "manajer IO baru baru" yang disebut MIO di mana "M" adalah singkatan dari multicore yang saya percaya. Itu dibangun di atas dasar manajer IO yang ada dan tujuan utamanya adalah untuk mengatasi penyebab penurunan kinerja 4+ core. Angka kinerja yang disediakan dalam makalah ini cukup mengesankan. Lihat dirimu sendiri:
Dan:
Mio telah membuatnya menjadi rilis GHC 7.8.1. Saya pribadi melihat ini sebagai langkah maju dalam kinerja Haskell. Akan sangat menarik untuk membandingkan kinerja aplikasi web yang ada yang disusun oleh versi GHC sebelumnya dan 7.8.1.
sumber
Peristiwa IMHO baik, tetapi pemrograman dengan cara callback tidak.
Sebagian besar masalah yang membuat pengkodean dan debugging aplikasi web khusus berasal dari apa yang membuatnya terukur dan fleksibel. Yang paling penting, sifat stateless HTTP. Ini meningkatkan kemampuan navigasi, tetapi ini memaksakan inversi kontrol di mana elemen IO (server web dalam hal ini) memanggil penangan yang berbeda dalam kode aplikasi. Model peristiwa ini - atau model panggilan balik, lebih tepatnya dikatakan - adalah mimpi buruk, karena panggilan balik tidak berbagi ruang lingkup variabel, dan tampilan navigasi yang intuitif hilang. Sangat sulit untuk mencegah semua kemungkinan perubahan status saat pengguna menavigasi bolak-balik, di antara masalah lainnya.
Dapat dikatakan bahwa masalahnya mirip dengan pemrograman GUI di mana model acara berfungsi dengan baik, tetapi GUI tidak memiliki navigasi dan tidak ada tombol kembali. Yang melipatgandakan transisi keadaan mungkin dalam aplikasi web. Hasil dari upaya untuk memecahkan masalah ini adalah kerangka kerja berat dengan konfigurasi rumit banyak pengidentifikasi sihir meresap tanpa mempertanyakan akar masalah: model callback dan kurangnya berbagi dari lingkup variabel, dan tidak ada urutan, sehingga urutan harus dibangun dengan menghubungkan pengidentifikasi.
Ada kerangka kerja berbasis sekuensial seperti ocsigen (ocaml) seaside (smalltalk) WASH (dihentikan, Haskell) dan mflow (Haskell) yang memecahkan masalah manajemen negara dengan tetap menjaga kemampuan navigasi dan keutuhan REST. dalam kerangka kerja ini, programmer dapat mengekspresikan navigasi sebagai urutan imperatif di mana program mengirim halaman dan menunggu tanggapan dalam satu utas, variabel dalam ruang lingkup dan tombol kembali bekerja secara otomatis. Ini secara inheren menghasilkan kode yang lebih pendek, lebih aman, lebih mudah dibaca di mana navigasi terlihat jelas oleh programmer. (peringatan wajar: Saya pengembang mflow)
sumber
Pertanyaannya cukup konyol karena 1) Haskell telah memecahkan masalah ini dengan cara yang jauh lebih baik dan 2) dengan cara yang kira-kira sama dengan Erlang. Inilah patokan terhadap simpul: http://www.yesodweb.com/blog/2011/03/preliminary-warp-cross-language-benchmarks
Berikan Haskell 4 core dan dapat melakukan permintaan 100r (sederhana) per detik dalam satu aplikasi. Node tidak dapat melakukan banyak hal, dan tidak dapat mengatur skala aplikasi tunggal lintas inti. Dan Anda tidak perlu melakukan apa pun untuk menuai ini karena runtime Haskell non-blocking. Satu-satunya bahasa (relatif umum) lainnya yang memiliki IO non-pemblokiran yang dibangun ke dalam runtime adalah Erlang.
sumber
pm2 -i max path/to/app.js
akan secara otomatis skala ke jumlah instance optimal berdasarkan core yang tersedia. Selain itu, Node juga non-pemblokiran secara default.Sama seperti nodejs telah menjatuhkan libev , Kerangka Web Snap Haskell juga telah menjatuhkan libev .
sumber