Bagaimana tidak menggunakan Node.js Stream API

Seseorang salah di Internet lagi - di Yesterday Node Weekly ada tautan ke pos tempat penulis mencoba mengukur dan membandingkan kinerja Stream API di Node.js. Kesedihan menyebabkan bagaimana penulis bekerja dengan aliran dan kesimpulan apa yang ia coba gambarkan berdasarkan ini:


... ini bekerja cukup baik pada file yang lebih kecil, tetapi begitu saya sampai pada file terbesar, kesalahan yang sama terjadi. Meskipun Node.js mengalirkan input dan output, Node.js masih berusaha menahan seluruh file dalam memori saat melakukan operasi

Mari kita coba mencari tahu apa yang salah dengan kesimpulan dan kode penulis.


Dari sudut pandang saya, masalahnya adalah bahwa penulis artikel tidak tahu cara menggunakan Stream'ami dan ini adalah masalah yang harus sering dihadapi. Fenomena ini, menurut saya, memiliki tiga alasan:


  1. Kisah kompleks Node.js Stream API - rasa sakit dan penderitaan yang dijelaskan di sini
  2. Bukan API paling intuitif jika Anda mencoba menggunakannya tanpa pembungkus
  3. Dokumentasi yang cukup aneh yang menghadirkan stream sebagai sesuatu yang sangat kompleks dan level rendah

Secara keseluruhan, ini mengarah pada fakta bahwa pengembang cukup sering tidak tahu bagaimana dan tidak ingin menggunakan API Stream.


Apa yang salah dengan kode penulis ?
Untuk memulai, mari ulangi tugas di sini (sumber asli dalam bahasa Inggris dan tautan ke file dapat ditemukan di pos):
Ada file 2,5 GB tertentu dengan garis-garis bentuk:


C00084871|N|M3|P|201703099050762757|15|IND|COLLINS, DARREN ROBERT|SOUTHLAKE|TX|760928782|CELANESE|VPCHOP&TECH|02282017|153||PR2552193345215|1151824||P/R DEDUCTION ($76.92 BI-WEEKLY)|4030920171380058715 

Anda perlu menguraikannya dan mencari tahu informasi berikut:


  • Jumlah baris dalam file
  • Nama pada baris 432 dan 43243 (di sini kebenaran muncul pertanyaan tentang bagaimana cara menghitung, dari 0 atau 1?)
  • Nama paling umum dan berapa kali itu terjadi
  • Jumlah angsuran untuk setiap bulan

Apa masalahnya? - Penulis dengan jujur โ€‹โ€‹mengatakan bahwa dia memuat seluruh file ke dalam memori dan karena ini, Node "hang" dan penulis memberi kita fakta yang menarik.


Fakta menyenangkan: Node.js hanya dapat menampung memori hingga 1,67GB pada satu waktu

Penulis membuat kesimpulan aneh dari fakta ini bahwa Aliran yang memuat seluruh file ke dalam memori, dan ia tidak menulis kode yang salah.
Mari kita membantah tesis: " Meskipun Node.js mengalirkan input dan output, itu masih berusaha untuk menahan seluruh file ", dengan menulis sebuah program kecil yang akan menghitung jumlah baris dalam file dengan ukuran berapa pun:


 const { Writable } = require('stream') const fs = require('fs') const split = require('split') let counter = 0 const linecounter = new Writable({ write(chunk, encoding, callback) { counter = counter + 1 callback() }, writev(chunks, callback) { counter = counter + chunks.length callback() } }) fs.createReadStream('itcont.txt') .pipe(split()) .pipe(linecounter) linecounter.on('finish', function() { console.log(counter) }) 

NB : kode ini sengaja ditulis sesederhana mungkin. Variabel global buruk!


Apa yang harus Anda perhatikan:


  • split - npm paket yang menerima aliran baris di "input" - mengembalikan aliran set baris ke "output" dengan jeda baris yang terpisah. Kemungkinan besar dibuat sebagai implementasi aliran Transformasi. Kami menyalurkannya ke ReadStream kami dengan file, dan pipa itu sendiri ke ...
  • linecounter - Implementasi WritableStream. Di dalamnya, kami menerapkan dua metode: untuk memproses satu potong (chunk) dan beberapa. "Baris" dalam situasi ini adalah baris kode. Membalik - menambahkan nomor yang diinginkan ke penghitung. Penting untuk memahami bahwa dalam situasi ini kami tidak akan memuat seluruh file ke dalam memori, dan API akan membagi semuanya untuk kami menjadi "bagian" yang paling nyaman untuk diproses
  • 'selesai' - peristiwa yang "terjadi" ketika data yang tiba di ReadableStream kami "berakhir". Ketika ini terjadi, kami menjanjikan data penghitung

Baiklah, mari kita uji kreasi kita pada file besar:


 > node linecounter.js 13903993 

Seperti yang Anda lihat, semuanya berfungsi. Dari apa yang dapat kita simpulkan bahwa Stream API melakukan pekerjaan yang sangat baik dengan file-file dari berbagai ukuran dan pernyataan dari penulis postingan, secara sederhana, itu tidak benar. Dengan cara yang kira-kira sama, kita dapat menghitung nilai lain yang diperlukan dalam masalah.


Katakan:


  • Apakah Anda tertarik membaca cara menyelesaikan masalah sepenuhnya dan cara membawa kode yang dihasilkan ke dalam bentuk yang mudah untuk pemeliharaan?
  • Apakah Anda menggunakan Stream API dan kesulitan apa yang Anda temui?

Source: https://habr.com/ru/post/id427901/


All Articles