paint-brush
Çoklu İşleme, JavaScript Uygulamamı 4 Kat Hızlandırmama Nasıl Yardımcı Oldu?ile@rusanov
2,797 okumalar
2,797 okumalar

Çoklu İşleme, JavaScript Uygulamamı 4 Kat Hızlandırmama Nasıl Yardımcı Oldu?

ile Dmitrii Rusanov5m2023/07/25
Read on Terminal Reader
Read this story w/o Javascript

Çok uzun; Okumak

İlgi çekici kod örnekleriyle Node.js'de çoklu işlemenin gizemini derinlemesine inceleyeceğiz.
featured image - Çoklu İşleme, JavaScript Uygulamamı 4 Kat Hızlandırmama Nasıl Yardımcı Oldu?
Dmitrii Rusanov HackerNoon profile picture
0-item
1-item

JavaScript doğası gereği tek iş parçacıklı bir canavar olarak tasarlanmıştır. Ancak bilişimin vahşi alanlarında, 'çoklu işlem' ve 'çok çekirdekli işlemciler' olarak bilinen yırtıcılar, kod yürütmenizi duyulmamış hızlara çıkarmaya hazır olarak evcilleştirilmeyi bekliyor. 💪🚀


Bu ormana adım atmaya cesaret ettim, kodumu nihai hayatta kalma testine tabi tuttum ve şaşırtıcı sonuçlarla ortaya çıktım. 🏆 Şimdi bu büyüleyici arayışta bana katılma sırası sizde. Node.js'de çoklu işlemenin gizemini derinlemesine araştıracağız, sürükleyici kod örnekleriyle donanmış olarak ve deneyimlerimin muhteşem meyveleri üzerine meşaleyi 🔦 parlatacağız. 🍎🍏


Çoklu işlemenin büyüsüyle JavaScript performansını güçlendiren bu adrenalin dolu maceraya yelken açmaya hazır olun! Yüksek oktanlı kodlamanın büyüleyici dünyasına adım atmak üzereyken kemerlerinizi bağlayın ve kendinizi hazırlayın.


Çok derinlere inmeden önce kendimizi bazı güvenilir araçlarla donatalım. Çoğu zaman zorlu hesaplama çalışmasını simüle etmek için birkaç yardımcı fonksiyon oluşturacağız. Yeni bir eser, utils.js adında bir dosya oluşturalım ve bu önemli büyüleri buraya yazalım.


 // 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, };

Tek iş parçacıklı versiyon

Tek bir iş parçacığında yürütme, problem çözme konusunda çalışkan ve güvenilir bir yaklaşımı temsil eder. Betiğin tek iş parçacıklı versiyonu görsel olarak bu şekilde tanımlanabilir. tek iplik Tek iş parçacıklı sürümün kodu oldukça basittir. Verileri oluşturuyoruz ve işlenmek üzere gönderiyoruz.

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

Betiği şu komutla başlatıyoruz: node sync.js

Bekliyoruz... bekliyoruz...ve bekliyoruz...

Yük ne kadar uzun olursa, kahve o kadar güçlü olur! Ve bu kadar bekledikten sonra betiğin çalışma zamanını belirten bir mesaj alıyoruz.


 single-thread. Time:: 25.888s


Bu yaklaşım çoğu durumda ihtiyaca uygundur. Ama bir aksaklık var. Aklı başında kim bekleme sanatına bayılır? Bu can sıkıcı gecikmenin üstesinden gelmek için bilgisayarlarımızın tüm ateş gücünü kullanmalıyız! Sonuçta çoğu modern bilgisayar birden fazla CPU çekirdeğiyle yüklü olarak gelir!


Peki, sayıları hesaplamak ve kod çalıştırmamızı güçlendirmek varken neden bu ek çekirdeklerin boşta kalmasına izin verelim ki? Uyuyan devleri aydınlatmanın ve çoklu işlemenin ham gücünü ortaya çıkarmanın zamanı geldi! Hadi dalalım!

Komut dosyasının Çok İşlemli versiyonu

Çok işlemli yaklaşımı benimseyerek, CPU'muzun birden çok çekirdeğinden yararlanabilir, betiğimizin performansını birkaç kat artırabiliriz. Çok işlemli kodumuzun çalışma süreci bu şema ile görselleştirilebilir.

çoklu işlem versiyonu Temelde, oldukça büyük bir veri kümesini bölümlere ayırıyoruz ve her bölümü işlenmek üzere ayrı bir CPU çekirdeğine atıyoruz.


multi-process.js başlıklı bir dosya oluşturun ve bu dosyayı aşağıdaki içerikle doldurun.


 // 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));


Bu kod, Node.js'deki çok işlemli veri işleme senfonisinde tek başına çalışan bir sürecin orkestrasyonunu ortaya çıkarır.


Kısaca olay şu:

  • Çalışan, verileri ve numarasını ana süreçten process.on('message') aracılığıyla alır.

  • processData işlevi, bu çalışana atanan veri kısmı üzerinde hesaplamalar gerçekleştirir.

  • Sonuç, `process.send()`` aracılığıyla ana işleme geri gönderilir.

  • Çalışan process.exit() aracılığıyla 0 koduyla sonlandırılır.


Komut dosyasını şu komutla çalıştırın: node multi-process.js

Turbo desteği için sıkı tutunun...

Hızlı yükleme Ve kodun 5 saniyede çalıştığı sonucuna varıyoruz!

 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 ]


Senaryomuz dört kat daha hızlı çalıştı! Bu muhteşem değil mi?

Büyük Açılış: Test Sonuçları

Heyecanlı bir merakla, her iki senaryoyu da 4 çekirdekli işlemciyle donatılmış bir bilgisayarda çalıştırdım ve büyünün ortaya çıkmasına tanık olmayı bekledim:


  • Tek iş parçacıklı senaryomuz olan solo sanatçı, verileri 25,8 saniyede özenle işledi.

  • Çok iş parçacıklı senaryomuz olan güçlü ekip, onu yalnızca 5,2 saniyede parkın dışına çıkardı!


Çoklu işlemenin gücüne bakın; hesaplama hızını dört kattan fazla artırın!

Bu keskin zıtlıklar, çoklu işlemenin makinenizin hesaplama yeteneklerini nasıl büyük ölçüde artırabileceğini ve yürütme süresini kısaltabileceğini vurguluyor.

Son düşünceler

Heyecan verici araştırmamız, çoklu işlemenin Node.js'deki hesaplama görevlerini nasıl hızlandırabileceğine dair canlı bir tablo çiziyor. Kodunuzu her bir işlemci çekirdeğine yaymak, performansta yürümeden ışınlanmaya geçişe benzer şekilde somut bir sıçrama sağlar!


Bu oku kodlama kılıfınıza eklemenize ve projelerinizde bu yaklaşımı denemenize kesinlikle değer. Node.js'de Worker Threads'in ortaya çıkışıyla birlikte çoklu işlemeyi uygulamak çocuk oyuncağı haline geldi.


Bunu okurken adrenalin patlaması yaşadınız mı? Node.js'de çoklu işlemeyle ilgili kendi maceralarınızı aşağıdaki yorumlarda paylaşmaktan çekinmeyin! Yüksek hızlı kodlamanın gizemlerini birlikte çözmeye devam edelim.