paint-brush
Como o multiprocessamento me ajudou a acelerar meu aplicativo JavaScript em 4xpor@rusanov
2,797 leituras
2,797 leituras

Como o multiprocessamento me ajudou a acelerar meu aplicativo JavaScript em 4x

por Dmitrii Rusanov5m2023/07/25
Read on Terminal Reader

Muito longo; Para ler

Vamos nos aprofundar no enigma do multiprocessamento em Node.js, armados com exemplos de código fascinantes.
featured image - Como o multiprocessamento me ajudou a acelerar meu aplicativo JavaScript em 4x
Dmitrii Rusanov HackerNoon profile picture
0-item
1-item

O JavaScript foi projetado inerentemente como uma fera de thread único. No entanto, nos terrenos selvagens da computação, os predadores conhecidos como 'multiprocessamento' e 'processadores multi-core' estão esperando para serem domados, prontos para aumentar a execução de seu código a velocidades inéditas. 💪🚀


Eu ousei entrar nesta selva, colocar meu código no teste de sobrevivência final e emergir com resultados surpreendentes. 🏆 Agora é a sua vez de se juntar a mim nesta fascinante missão. Vamos nos aprofundar no enigma do multiprocessamento em Node.js , munidos de exemplos de código fascinantes e iluminando com a tocha 🔦 os frutos espetaculares de meus experimentos. 🍎🍏


Prepare-se para embarcar nesta aventura movida a adrenalina de turbinar o desempenho do JavaScript por meio da magia do multiprocessamento! Aperte o cinto e prepare-se, pois estamos prestes a entrar no reino hipnotizante da codificação de alta octanagem.


Antes de nos aventurarmos muito fundo, vamos nos equipar com algumas ferramentas confiáveis. Criaremos algumas funções auxiliares para simular o frequentemente árduo trabalho computacional. Vamos criar um novo artefato, um arquivo chamado utils.js , e inscrever esses encantamentos essenciais nele.


 // utils.js function generateRandomData(size) { const data = []; for (let i = 0; i < size; i++) { data.push(Math.random()); } return data; } function processData(data) { // performs some calculations on the array // to simulate high resource intensity let sum = 0; for (let num of data) { for (let j = 0; j < 1000000; j++) { sum += Math.sqrt(num); } } return sum; } module.exports = { generateRandomData, processData, };

Versão de thread único

A execução em um único thread representa uma abordagem trabalhadora e confiável para a solução de problemas. A versão de thread único do script pode ser descrita visualmente como tal. fio único O código da versão single-threaded é bastante direto. Criamos dados e os enviamos para processamento.

 // sync.js const { generateRandomData, processData } = require("./utils"); const data = generateRandomData(30000); console.time("single-thread. Time:"); processData(data); console.timeEnd("single-thread. Time:");

Iniciamos o script com o comando: node sync.js

Esperamos... e esperamos... e esperamos...

Quanto maior a carga, mais forte o café! E após toda essa espera, recebemos uma mensagem indicando o tempo de execução do script.


 single-thread. Time:: 25.888s


Essa abordagem é adequada para a maioria dos casos. Mas há um soluço. Quem, em sã consciência, adora a arte de esperar? Para superar esse atraso agonizante, devemos aproveitar todo o poder de fogo de nossos computadores! Afinal, a maioria dos computadores modernos vem carregada com mais de um único núcleo de CPU!


Então, por que devemos deixar esses núcleos adicionais ficarem ociosos quando eles podem estar processando números e sobrecarregando nossa execução de código ? É hora de iluminar aqueles gigantes adormecidos e liberar o poder bruto do multiprocessamento! Vamos mergulhar!

Versão multiprocessada do script

Adotando a abordagem multiprocessada, podemos alavancar vários núcleos de nossa CPU, impulsionando o desempenho de nosso script várias vezes. O processo de operação do nosso código multiprocessado pode ser visualizado com este diagrama.

versão de multiprocessamento Em essência, estamos simplesmente particionando um conjunto de dados considerável em segmentos e atribuindo cada segmento para processamento a um núcleo de CPU discreto.


Crie um arquivo intitulado multi-process.js e preencha-o com o seguinte conteúdo.


 // multi-process.js const childProcess = require("child_process"); const utils = require("./utils"); const data = utils.generateRandomData(30000); const chunkSize = Math.ceil(data.length / 4); const chunks = []; for (let i = 0; i < 4; i++) { const start = i * chunkSize; const end = start + chunkSize; chunks.push(data.slice(start, end)); } console.time("multiProcessed"); const workers = []; let results = []; // result collection array for (let i = 0; i < chunks.length; i++) { const worker = childProcess.fork("./worker.js"); // pass its number and data to the workflow worker.send({ workerNumber: i, data: chunks[i] }); workers.push( new Promise((resolve, reject) => { worker.on("message", (result) => { results.push(result); // add the result to the result array resolve(); }); worker.on("error", reject); worker.on("exit", (code) => { if (code !== 0) { reject(new Error(`Worker stopped with exit code ${code}`)); } }); }) ); } Promise.all(workers) .then(() => { console.timeEnd("multiProcessed"); console.log("Processing results:", results); }) .catch((err) => console.error(err));


Este código revela a orquestração de um processo de trabalho solitário na sinfonia da manipulação de dados multiprocessados em Node.js.


Em resumo, aqui está o que está acontecendo:

  • O trabalhador recebe dados e seu número do processo principal via process.on('message') .

  • A função processData realiza cálculos na porção de dados atribuída a este trabalhador.

  • O resultado é enviado de volta ao processo principal via `process.send()``.

  • O trabalhador termina com o código 0 via process.exit() .


Inicie o script com o comando: node multi-process.js

Segure firme para o turbo boost...

Carregamento rápido E chegamos à conclusão de que o código funcionou em 5 segundos!

 Worker 0 started Worker 1 started Worker 2 started Worker 3 started ==================== Worker 1 finished ==================== Worker 2 finished ==================== Worker 3 finished ==================== Worker 0 finished multiProcessed: 5.266s Processing results: [ 4971422688.053512, 4989646323.157899, 4999088030.661542, 5008034869.924775 ]


Nosso script funcionou quatro vezes mais rápido! Isso não é magnífico?

A Grande Revelação: Resultados de Testes

Com muita curiosidade, executei os dois scripts em um computador equipado com um processador de 4 núcleos, esperando para testemunhar o desenrolar da mágica:


  • O artista solo, nosso script de thread único, processou diligentemente os dados em 25,8 segundos .

  • A equipe poderosa, nosso script multi-threaded, o tirou do parque em apenas 5,2 segundos !


Contemple o poder do multiprocessamento – mais do que quadruplicar a velocidade dos cálculos!

Esses contrastes gritantes destacam como o multiprocessamento pode ampliar drasticamente os recursos computacionais de sua máquina e reduzir o tempo de execução.

Pensamentos finais

Nossa emocionante exploração mostra um quadro vívido de como o multiprocessamento pode turbinar as tarefas computacionais no Node.js. Liberar seu código em cada núcleo do processador oferece um salto tangível no desempenho, semelhante à mudança da caminhada para o teletransporte!


Definitivamente, vale a pena adicionar esta seta à sua aljava de codificação e experimentar essa abordagem em seus projetos. E com o advento dos Worker Threads no Node.js, a implementação do multiprocessamento tornou-se muito fácil.


Sentiu uma descarga de adrenalina lendo isso? Sinta-se à vontade para compartilhar suas próprias aventuras com multiprocessamento em Node.js nos comentários abaixo! Vamos continuar a desvendar os mistérios da codificação de alta velocidade juntos.