Menggunakan Webassembly dan Rust Bersama-sama Meningkatkan Kinerja Node.Js.

Menggunakan Webassembly dan Rust Bersama-sama Meningkatkan Kinerja Node.Js. – Pernahkah Anda atau tim Anda mengalami situasi di mana kecepatan aplikasi dan produktivitas pengembang sangat penting, tetapi tuntutan bisnis berubah dengan cepat? Saya bekerja di tim Metode Garasi IBM, dan tim saya menemukan diri kami sendiri dalam situasi yang persis seperti ini ketika saya ditugaskan untuk menemukan solusi dan membuat transpiler bukti konsep untuk file konten tim kami.

Menggunakan Webassembly dan Rust Bersama-sama Meningkatkan Kinerja Node.Js.

Saya perlu menemukan tumpukan teknologi yang akan memungkinkan kami untuk menyampaikan di semua lini dan, pada saat yang sama, menjadi sesuatu yang terintegrasi dengan baik dengan toolchain kami yang ada. Artikel berikut merinci bagaimana saya memutuskan untuk menggunakan Rust bersama dengan WebAssembly dan berbicara tentang mengapa kombinasi dari kedua teknologi tersebut begitu kuat. idnplay

Perjalanan menuju Rust dan WebAssembly

Persyaratan bisnis

Pertama, izinkan saya untuk menguraikan tuntutan bisnis yang saya sebutkan sebelumnya. Tim kami sedang dalam proses penulisan ulang dan pemfaktoran ulang seluruh aplikasi kami yang saat ini menggunakan bahasa khusus domain (DSL) untuk semua konten kami. Kami memiliki ribuan file ini, dengan total lebih dari satu gigabyte konten, dan terkadang, kami bahkan memiliki beberapa template yang terdapat dalam file yang sama. https://www.premium303.pro/

Untuk penulisan ulang yang sukses, kami perlu mengotomatiskan cara kami memindahkan konten ke sistem baru. Kami juga harus mempertimbangkan bahwa ratusan penulis konten kami telah dilatih tentang cara menggunakan DSL ini, jadi setiap perubahan akan mengharuskan mereka untuk beradaptasi dengan sistem yang baru. Dengan persyaratan tersebut, kami harus memutuskan di antara dua opsi:

  • Alat baris perintah yang akan kami jalankan satu kali untuk melakukan migrasi massal konten yang ada. Penulis konten akan mempelajari sistem baru.
  • Alat baris perintah yang dapat kita jalankan sebagai migrasi massal ATAU sebagai cara untuk menjalankan file yang diubah secara lokal untuk lebih banyak build tambahan sehingga penulis dapat terus menggunakan sistem yang ada.

Karena tim kami membutuhkan fleksibilitas maksimum dan menurut kami tidak mungkin untuk melatih kembali semua penulis konten kami, kami memutuskan untuk menggunakan opsi kedua dan membangun alat yang dapat kami jalankan baik sekali atau sebagai langkah pembuatan tambahan.

Pertimbangan kinerja

Salah satu pertimbangan kinerja pertama kami terkait dengan kecepatan: Jika kami berharap menjalankan ini setiap kali seseorang melakukan perubahan, proses transpiling harus cepat dan terjadi dalam hitungan detik. Dalam salah satu skenario kami, kami mempertimbangkan untuk mengekspos alat sebagai API yang mengubah konten dan menyajikan hasil yang ditranspilasi kembali ke klien. Solusi ini sangat meningkatkan pertimbangan kinerja, karena beberapa dari file ini dapat berukuran lebih dari satu megabyte sendiri. Dengan kasus ini, file akan dikirim, diurai, dirender ke format baru, dikompresi, dan kemudian dikirim ke klien dalam beberapa detik. Jadi, kecepatan adalah pertimbangan utama.

Pertimbangan utama kedua adalah kemampuan untuk menjalankan transpiler di web. Banyak bahasa dapat memproses file-file ini dengan cepat di komputer lokal, tetapi jauh lebih sedikit yang mencapai kecepatan yang mendekati aslinya jika dipindahkan ke web.

Terakhir, kami membutuhkan bahasa yang dapat kami integrasikan dengan mudah dan efisien dengan lingkungan berbasis Node.js. Tim kami menghargai ekosistem Node.js, dan aplikasi yang baru direfraktorisasi akan menjadi klien berbasis Vue dengan backend berbasis Express yang diimplementasikan sebagai REST API. Perkakas Node, komunitas sumber terbuka, dan kemampuan untuk menulis klien dan server kami dalam bahasa yang sama (dalam kasus kami, Typecript) adalah keuntungan besar bagi jadwal pengiriman cepat tim kami. Kami tahu kami harus mempertahankan manfaat luar biasa ini untuk aplikasi kami, tetapi kami juga tahu bahwa untuk mendapatkan kinerja yang kami butuhkan, kami harus mencari di tempat lain. Jadi, memiliki integrasi yang sangat baik dengan aplikasi Node utama kami adalah kebutuhan mutlak.

Setelah kami memahami persyaratan bisnis kami, sekarang saatnya untuk memetik beberapa bukti konsep.

Bukti konsep pertama: Scala

Proses pemikiran awal saya adalah mencari bahasa dengan properti berikut:

  • Dukungan pemrograman fungsional
  • Mapan dengan bisnis besar yang menggunakannya dalam produksi
  • Kemampuan terdokumentasi untuk bekerja dengan baik sebagai bahasa untuk parsing
  • Kemampuan untuk berinteraksi dengan Node.js dan JavaScript

Daftar persyaratan ini awalnya membuat saya melihat Scala karena mencentang semua kotak yang tercantum di atas: bahasa mapan di atas Java Virtual Machine (JVM), dukungan pemrograman fungsional yang hebat, dokumentasi yang menunjukkan bahwa ia bekerja dengan baik sebagai bahasa parsing, dan – dengan Scala.js – cara yang layak untuk bekerja dengan Node dan JavaScript.

Setelah awalnya mengerjakan modul parsing dengan Scala, saya dapat mencapai jumlah kemajuan yang layak, bahkan mengurai aturan dasar DSL kami (berdasarkan Handlebars dan Markdown). Namun, ketika saya melanjutkan, saya dengan cepat menemukan banyak masalah dengan arsitektur.

Ditambah lagi, pengembangan di Scala sangat lambat. Pengujian untuk pengembangan yang digerakkan oleh pengujian dengan mudah membutuhkan waktu 5+ menit untuk dijalankan setiap saat, sangat memperlambat prosesnya. Itu juga gagal dalam kategori kinerja, dengan tes penguraian dasar yang berlangsung dari 500-1000ms dalam konfigurasi pengembangan hingga 300-450ms dalam konfigurasi rilis.

Bukti konsep kedua: Rust

Setelah menemukan Scala tidak cocok untuk kebutuhan kami, saya mulai mencari alternatif lain – dan Rust adalah salah satu yang pertama dalam daftar saya karena saya telah bekerja dengan Rust selama satu setengah tahun. Rust mencentang semua kotak yang disebutkan di POC pertama, dan, yang terpenting, memiliki dukungan yang sangat baik untuk WebAssembly. Pertama, saya membuat prototipe fungsionalitas baru untuk parser di Rust, dan kemudian menerjemahkannya ke Scala pada saat yang sama saya menulis tes dan tolok ukur untuk keduanya.

Saya segera menyadari bahwa bekerja dengan Rust lebih mudah daripada dengan Scala, dan dapat dengan cepat mengembangkan solusi baru dan aturan parsing. Saya juga menemukan bahwa menjalankan pengujian unit dan penguraian itu sendiri semuanya jauh lebih cepat. Saya mengirim contoh kode dari fungsi yang sama yang ditulis di Scala dan Rust ke beberapa anggota tim saya dan pimpinan pengembangan kami. Mereka semua menemukan kode Rust jauh lebih mudah untuk dipahami, dan saat itulah pimpinan pengembang kami setuju untuk memindahkan upaya saya ke Rust sebagai POC kedua.

Hasilnya luar biasa untuk tim kami! Sebagai permulaan, saya memindahkan semua pekerjaan kami sebelumnya di Scala ke Rust hanya dalam satu setengah minggu. Setelah beberapa minggu lagi, saya telah menerapkan lebih banyak aturan penguraian. Pada titik ini, kami ingin melihat peningkatan performa seperti apa yang kami dapat dari Rust, dan, sekali lagi, hasilnya luar biasa! Silakan dan tebak peningkatan persentase yang kami lihat dalam kinerja dalam mode rilis? 200%? 400%? 800%? Tidak, semua tebakan bagus, tapi kami melihat peningkatan kecepatan yang luar biasa 1200-1500%! Kami beralih dari 300-450ms dalam mode rilis dengan Scala dengan penerapan aturan parsing yang lebih sedikit, menjadi 25-30ms di Rust dengan lebih banyak aturan parsing yang diterapkan!

Pada titik ini, dengan kemampuan Rust untuk berintegrasi dengan begitu mudah dengan Node.js dan tim kami secara keseluruhan, dan peningkatan kinerja luar biasa yang membuat CLI dan kemungkinan API menjadi layak, kami tahu akhirnya kami memiliki kombinasi yang unggul.

Menggunakan Webassembly dan Rust Bersama-sama Meningkatkan Kinerja Node.Js.

Peningkatan kecepatan 1200-1500% kami mungkin bukan hal yang biasa, tetapi ada contoh lain dari perusahaan yang telah mulai beralih ke Rust yang mencapai 200% plus peningkatan kecepatan melalui Java dan sangat mengurangi konsumsi memori.

Sekarang setelah Anda memahami cara kerja teknologi ini untuk tim kami, mari kita bicara sedikit tentang teknologi itu sendiri dan mengapa teknologi ini sangat populer.…