Como não usar a API de fluxo do Node.js.

Alguém está errado na Internet novamente - no Node Weekly de ontem, havia um link para uma postagem na qual o autor está tentando medir e comparar o desempenho da API de fluxo no Node.js. A tristeza causa como o autor trabalha com fluxos e que conclusões ele tenta tirar com base nisso:


... isso funcionou muito bem em arquivos menores, mas quando cheguei ao arquivo maior, ocorreu o mesmo erro. Embora o Node.js estivesse transmitindo as entradas e saídas, ele ainda tentou manter o arquivo inteiro na memória enquanto executava as operações

Vamos tentar descobrir o que há de errado com as conclusões e o código do autor.


Do meu ponto de vista, o problema é que o autor do artigo não sabe como usar o Stream'ami e esse é um problema que você precisa encontrar com frequência. Este fenômeno, na minha opinião, tem três razões:


  1. A história complexa da API de fluxo do Node.js. - a dor e o sofrimento descritos aqui
  2. Não é a API mais intuitiva se você tentar usá-la sem invólucros
  3. Documentação bastante estranha que apresenta fluxos como algo muito complexo e de baixo nível

Em conjunto, isso leva ao fato de que os desenvolvedores geralmente não sabem como e não querem usar a API de Stream.


O que há de errado com o código do autor ?
Para começar, repita a tarefa aqui (o original em inglês e um link para o arquivo podem ser encontrados na postagem):
Há um certo arquivo de 2,5 GB com linhas no formato:


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 

Você precisa analisá-lo e descobrir as seguintes informações:


  • O número de linhas no arquivo
  • Nomes nas 432ª e 43243ª linhas (aqui a verdade surge a questão de como contar, de 0 ou 1?)
  • O nome mais comum e quantas vezes ocorre
  • O número de parcelas para cada mês

Qual é o problema? - O autor diz honestamente que carrega o arquivo inteiro na memória e, por causa disso, o Node "trava" e o autor nos fornece um fato interessante.


Curiosidade: o Node.js pode armazenar apenas 1,67 GB de memória por vez

O autor faz uma conclusão estranha desse fato: são os Streams que carregam o arquivo inteiro na memória e ele não escreveu o código errado.
Vamos refutar a tese: " Embora o Node.js estivesse transmitindo as entradas e saídas, ele ainda tenta armazenar o arquivo inteiro ", escrevendo um pequeno programa que contará o número de linhas em um arquivo de qualquer tamanho:


 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) }) 

Nota : o código foi intencionalmente escrito da maneira mais simples possível. Variáveis ​​globais são ruins!


O que você deve prestar atenção:


  • split - npm um pacote que recebe um fluxo de linhas na "entrada" - retorna um fluxo de conjuntos de linhas para a "saída" com uma quebra de linha separada. Provavelmente feito como uma implementação do fluxo de transformação. Nós canalizamos nele nosso ReadStream com um arquivo e ...
  • linecounter - Implementação do WritableStream. Nele, implementamos dois métodos: para processar uma peça (chunk) e várias. A "linha" nesta situação é a linha de código. Inverter - adicione o número desejado ao contador. É importante entender que nessa situação não carregaremos o arquivo inteiro na memória, e a API dividirá tudo para nós em "partes" mais convenientes para o processamento
  • 'finish' - eventos que “acontecem” quando os dados que chegam ao nosso ReadableStream “terminam”. Quando isso acontece, prometemos dados do contador

Bem, vamos testar nossa criação em um arquivo grande:


 > node linecounter.js 13903993 

Como você pode ver, tudo funciona. Pelo que podemos concluir que a API Stream faz um excelente trabalho com arquivos de qualquer tamanho e a declaração do autor da postagem, para dizer o mínimo, não é verdadeira. Aproximadamente da mesma maneira, podemos calcular qualquer outro valor necessário no problema.


Diga:


  • Você está interessado em ler como resolver o problema completamente e como colocar o código resultante em um formulário conveniente para manutenção?
  • Você usa a API do Stream e quais dificuldades você encontrou?

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


All Articles