ParallelJS:優雅的Web Worker解決方案
ParallelJS為使用Web Worker時可能出現的問題提供了一種優雅的解決方案,它提供了一個具有便捷抽象和輔助工具的實用API。 HTML5引入的Worker接口允許創建具有較長運行時間和高計算量需求的函數,這些函數可以同時使用以提高網站響應速度。 ParallelJS允許對JavaScript代碼進行並行化處理,利用同時多線程 (SMT) 更有效地使用現代CPU。 ParallelJS庫提供諸如spawn
、map
和reduce
等方法,分別用於並行執行計算、處理數據和聚合碎片化結果。
HTML5帶來的一個最酷的新可能性是Web Workers API的Worker接口。在此之前,我們不得不採用一些技巧來向用戶展示響應迅速的網站。 Worker接口允許我們創建具有較長運行時間和高計算量需求的函數。此外,Worker實例可以同時使用,使我們能夠根據需要生成任意數量的這些工作器。在本文中,我將討論為什麼多線程很重要,以及如何使用ParallelJS在JavaScript中實現它。
為什麼需要多線程?
這是一個合理的問題。從歷史上看,生成線程的能力提供了一種優雅的方式來劃分進程中的工作。操作系統負責調度每個線程的可用時間,這樣優先級更高、工作量更大的線程將優先於低優先級的空閒線程。在過去的幾年裡,同時多線程 (SMT) 已經成為訪問現代CPU計算能力的關鍵。原因很簡單:摩爾定律在每單位面積晶體管數量方面仍然有效。然而,由於多種原因,頻率縮放不得不停止。因此,必須以其他方式使用可用的晶體管。人們決定,架構改進(例如SIMD)和多核代表最佳選擇。
為了使用SMT,我們需要編寫並行代碼,即為獲得單個結果而並行運行的代碼。我們通常需要考慮特殊的算法,因為大多數順序代碼要么很難並行化,要么效率非常低。原因在於Amdahl定律,該定律指出加速比S由下式給出:
其中N是並行工作器的數量(例如處理器、核心或線程),P是並行部分。將來可能會使用更多依賴於並行算法的多核架構。在高性能計算領域,GPU系統和特殊架構(例如英特爾至強Phi)代表了此類平台。最後,我們應該區分一般的並發應用程序或算法和並行執行。並行性是(可能相關的)計算的同時執行。相反,並發是獨立執行進程的組合。
JavaScript中的多線程
在JavaScript中,我們已經知道如何編寫並發程序,即使用回調函數。現在可以將此知識轉移到創建並行程序中!根據其自身的結構,JavaScript是在由事件循環(通常遵循反應器模式)調解的單個線程中執行的。例如,這為我們處理對(外部)資源的異步請求提供了一些很好的抽象。它還保證先前定義的回調始終在相同的執行線程中觸發。沒有與線程相關的跨線程異常、競爭條件或其他問題。但是,這並沒有讓我們更接近JavaScript中的SMT。隨著Worker接口的引入,已經找到了一個優雅的解決方案。從主應用程序的角度來看,Web Worker中的代碼應被視為並發運行的任務。通信也是以這種方式進行的。我們使用消息API,該API也可用於從包含的網站到託管頁面的通信。例如,以下代碼通過向發起者發送消息來響應傳入的消息。
window.addEventListener('message', function (event) { event.source.postMessage('Howdy Cowboy!', event.origin); }, false);
理論上,Web Worker也可以生成另一個Web Worker。但是,實際上大多數瀏覽器禁止這樣做。因此,Web Worker之間通信的唯一方法是通過主應用程序。通過消息進行的通信是並發進行的,因此只有異步(非阻塞)通信。起初,這在編程中可能很奇怪,但它帶來了許多優點。最重要的是,我們的代碼應該沒有競爭條件!讓我們來看一個使用兩個參數表示序列的開始和結束來在後台計算素數序列的簡單示例。首先,我們創建一個名為prime.js的文件,其中包含以下內容:
onmessage = function (event) { var arguments = JSON.parse(event.data); run(arguments.start, arguments.end); }; function run (start, end) { var n = start; while (n < end) { var k = Math.sqrt(n); var found = false; for (var i = 2; !found && i <= k; i++) { found = n % i === 0; } if (!found) { postMessage(n.toString()); } n++; } }
現在,我們只需要在主應用程序中使用以下代碼來啟動後台工作器即可。
if (typeof Worker !== 'undefined') { var w = new Worker('prime.js'); w.onmessage = function(event) { console.log(event); }; var args = { start : 100, end : 10000 }; w.postMessage(JSON.stringify(args)); }
相當多的工作。尤其令人討厭的是使用另一個文件。這產生了很好的分離,但對於較小的任務似乎完全是多餘的。幸運的是,有一種解決方法。考慮以下代碼:
var fs = (function () { /* code for the worker */ }).toString(); var blob = new Blob( [fs.substr(13, fs.length - 14)], { type: 'text/javascript' } ); var url = window.URL.createObjectURL(blob); var worker = new Worker(url); // Now setup communication and rest as before
當然,我們可能希望有一個比這樣的幻數(13和14)更好的解決方案,並且根據瀏覽器,必須使用Blob和createObjectURL的回退。如果您不是JavaScript專家,fs.substr(13, fs.length - 14)的作用是提取函數體。我們通過將函數聲明轉換為字符串(使用toString()調用)並刪除函數本身的簽名來做到這一點。
ParallelJS能幫上忙嗎?
這就是ParallelJS發揮作用的地方。它為一些便利以及Web Worker提供了一個不錯的API。它包括許多輔助工具和非常有用的抽象。我們首先提供一些要處理的數據。
var p = new Parallel([1, 2, 3, 4, 5]); console.log(p.data);
data字段產生提供的數組。還沒有調用任何“並行”操作。但是,實例p包含一組方法,例如spawn,它將創建一個新的Web Worker。它返回一個Promise,這使得使用結果變得輕而易舉。
window.addEventListener('message', function (event) { event.source.postMessage('Howdy Cowboy!', event.origin); }, false);
上面代碼的問題是計算不會真正並行。我們只創建一個單個後台工作器,它一次性處理整個數據數組。只有在處理完整個數組後,我們才能獲得結果。更好的解決方案是使用Parallel實例的map函數。
onmessage = function (event) { var arguments = JSON.parse(event.data); run(arguments.start, arguments.end); }; function run (start, end) { var n = start; while (n < end) { var k = Math.sqrt(n); var found = false; for (var i = 2; !found && i <= k; i++) { found = n % i === 0; } if (!found) { postMessage(n.toString()); } n++; } }
在前面的示例中,核心非常簡單,可能過於簡單。在一個真實的示例中,將涉及許多操作和函數。我們可以使用require函數包含引入的函數。
if (typeof Worker !== 'undefined') { var w = new Worker('prime.js'); w.onmessage = function(event) { console.log(event); }; var args = { start : 100, end : 10000 }; w.postMessage(JSON.stringify(args)); }
reduce函數有助於將碎片化的結果聚合到單個結果中。它提供了一個方便的抽象,用於收集子結果並在知道所有子結果後執行某些操作。
結論
ParallelJS為我們提供了一種優雅的方式來規避使用Web Worker時可能出現的問題。此外,我們獲得了一個包含一些有用抽象和輔助工具的不錯的API。將來可以集成進一步的改進。除了能夠在JavaScript中使用SMT之外,我們可能還想使用矢量化功能。如果支持,SIMD.js似乎是一種可行的方法。在某些(希望不會太遙遠的)將來,使用GPU進行計算也可能是一個有效的選項。在Node.js中存在CUDA(一種並行計算架構)的包裝器,但是仍然無法執行原始JavaScript代碼。在那之前,ParallelJS是我們充分利用多核CPU處理長時間運行計算的最佳選擇。你呢?你如何使用JavaScript釋放現代硬件的強大功能?
關於使用ParallelJS的並行JavaScript的常見問題解答 (FAQ)
什麼是ParallelJS,它是如何工作的?
ParallelJS是一個JavaScript庫,允許您通過利用多核處理器來並行化數據處理。它的工作原理是創建一個新的Parallel對象並將一個數據數組傳遞給它。然後可以使用.map()
方法並行處理此數據,該方法將指定的函數應用於數組中的每個項目。然後在新的數組中返回結果。
如何安裝ParallelJS?
可以使用npm(Node.js包管理器)安裝ParallelJS。只需在終端中運行命令“npm install paralleljs”。安裝完成後,您可以使用“var Parallel = require('paralleljs');”在您的JavaScript文件中引用它。
使用ParallelJS的好處是什麼?
ParallelJS允許您充分利用多核處理器進行數據處理任務。這可以大大加快大型數據集的處理時間。它還提供了一個簡單直觀的API,使並行化代碼變得容易。
我可以在瀏覽器中使用ParallelJS嗎?
是的,ParallelJS可以在瀏覽器中使用。您可以使用腳本標籤和ParallelJS文件的URL將其包含在HTML文件中。包含後,您可以像在Node.js中一樣使用Parallel對象。
如何在ParallelJS中使用.map()
方法?
ParallelJS中的.map()
方法用於將函數應用於數據數組中的每個項目。該函數作為字符串傳遞給.map()
方法。然後在新的數組中返回結果。例如,“var p = new Parallel([1, 2, 3]); p.map('function(n) { return n * 2; }');”將返回一個值為[2, 4, 6]的新數組。
ParallelJS中的.reduce()
方法是什麼?
ParallelJS中的.reduce()
方法用於使用指定的函數將數據數組減少為單個值。該函數作為字符串傳遞給.reduce()
方法。例如,“var p = new Parallel([1, 2, 3]); p.reduce('function(a, b) { return a b; }');”將返回值6。
我可以在ParallelJS中鏈接方法嗎?
是的,ParallelJS中的方法可以鏈接在一起。例如,您可以使用.map()
方法處理數據,然後使用.reduce()
方法將結果組合成單個值。
如何在ParallelJS中處理錯誤?
可以使用.catch()
方法處理ParallelJS中的錯誤。此方法接受一個函數,如果在處理過程中發生錯誤,則會調用該函數。錯誤對象將傳遞給此函數。
我可以將ParallelJS與其他JavaScript庫一起使用嗎?
是的,ParallelJS可以與其他JavaScript庫一起使用。但是,您需要確保使用.require()
方法將庫包含在worker上下文中。
ParallelJS適用於所有數據處理任務嗎?
雖然ParallelJS可以大大加快大型數據集的處理時間,但它可能並非所有任務的最佳選擇。對於小型數據集,創建worker和傳輸數據的開銷可能超過並行化的益處。最好使用您的具體用例測試ParallelJS,以查看它是否提供了性能優勢。
以上是並聯JavaScript的詳細內容。更多資訊請關注PHP中文網其他相關文章!

Python和JavaScript的主要區別在於類型系統和應用場景。 1.Python使用動態類型,適合科學計算和數據分析。 2.JavaScript採用弱類型,廣泛用於前端和全棧開發。兩者在異步編程和性能優化上各有優勢,選擇時應根據項目需求決定。

選擇Python還是JavaScript取決於項目類型:1)數據科學和自動化任務選擇Python;2)前端和全棧開發選擇JavaScript。 Python因其在數據處理和自動化方面的強大庫而備受青睞,而JavaScript則因其在網頁交互和全棧開發中的優勢而不可或缺。

Python和JavaScript各有優勢,選擇取決於項目需求和個人偏好。 1.Python易學,語法簡潔,適用於數據科學和後端開發,但執行速度較慢。 2.JavaScript在前端開發中無處不在,異步編程能力強,Node.js使其適用於全棧開發,但語法可能複雜且易出錯。

javascriptisnotbuiltoncorc; sanInterpretedlanguagethatrunsonenginesoftenwritteninc.1)JavascriptwasdesignedAsignedAsalightWeight,drackendedlanguageforwebbrowsers.2)Enginesevolvedfromsimpleterterpretpretpretpretpreterterpretpretpretpretpretpretpretpretpretcompilerers,典型地,替代品。

JavaScript可用於前端和後端開發。前端通過DOM操作增強用戶體驗,後端通過Node.js處理服務器任務。 1.前端示例:改變網頁文本內容。 2.後端示例:創建Node.js服務器。

選擇Python還是JavaScript應基於職業發展、學習曲線和生態系統:1)職業發展:Python適合數據科學和後端開發,JavaScript適合前端和全棧開發。 2)學習曲線:Python語法簡潔,適合初學者;JavaScript語法靈活。 3)生態系統:Python有豐富的科學計算庫,JavaScript有強大的前端框架。

JavaScript框架的強大之處在於簡化開發、提升用戶體驗和應用性能。選擇框架時應考慮:1.項目規模和復雜度,2.團隊經驗,3.生態系統和社區支持。

引言我知道你可能會覺得奇怪,JavaScript、C 和瀏覽器之間到底有什麼關係?它們之間看似毫無關聯,但實際上,它們在現代網絡開發中扮演著非常重要的角色。今天我們就來深入探討一下這三者之間的緊密聯繫。通過這篇文章,你將了解到JavaScript如何在瀏覽器中運行,C 在瀏覽器引擎中的作用,以及它們如何共同推動網頁的渲染和交互。 JavaScript與瀏覽器的關係我們都知道,JavaScript是前端開發的核心語言,它直接在瀏覽器中運行,讓網頁變得生動有趣。你是否曾經想過,為什麼JavaScr


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能

SublimeText3 Linux新版
SublimeText3 Linux最新版

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

Safe Exam Browser
Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

Dreamweaver Mac版
視覺化網頁開發工具