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中文網其他相關文章!

JavaScript字符串替換方法詳解及常見問題解答 本文將探討兩種在JavaScript中替換字符串字符的方法:在JavaScript代碼內部替換和在網頁HTML內部替換。 在JavaScript代碼內部替換字符串 最直接的方法是使用replace()方法: str = str.replace("find","replace"); 該方法僅替換第一個匹配項。要替換所有匹配項,需使用正則表達式並添加全局標誌g: str = str.replace(/fi

本教程向您展示瞭如何將自定義的Google搜索API集成到您的博客或網站中,提供了比標準WordPress主題搜索功能更精緻的搜索體驗。 令人驚訝的是簡單!您將能夠將搜索限制為Y

利用輕鬆的網頁佈局:8 ESTISSEL插件jQuery大大簡化了網頁佈局。 本文重點介紹了簡化該過程的八個功能強大的JQuery插件,對於手動網站創建特別有用

因此,在這裡,您準備好了解所有稱為Ajax的東西。但是,到底是什麼? AJAX一詞是指用於創建動態,交互式Web內容的一系列寬鬆的技術。 Ajax一詞,最初由Jesse J創造

核心要點 JavaScript 中的 this 通常指代“擁有”該方法的對象,但具體取決於函數的調用方式。 沒有當前對象時,this 指代全局對象。在 Web 瀏覽器中,它由 window 表示。 調用函數時,this 保持全局對象;但調用對象構造函數或其任何方法時,this 指代對象的實例。 可以使用 call()、apply() 和 bind() 等方法更改 this 的上下文。這些方法使用給定的 this 值和參數調用函數。 JavaScript 是一門優秀的編程語言。幾年前,這句話可

該帖子編寫了有用的作弊表,參考指南,快速食譜以及用於Android,BlackBerry和iPhone應用程序開發的代碼片段。 沒有開發人員應該沒有他們! 觸摸手勢參考指南(PDF)是Desig的寶貴資源

jQuery是一個很棒的JavaScript框架。但是,與任何圖書館一樣,有時有必要在引擎蓋下發現發生了什麼。也許是因為您正在追踪一個錯誤,或者只是對jQuery如何實現特定UI感到好奇


熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

Atom編輯器mac版下載
最受歡迎的的開源編輯器

Dreamweaver CS6
視覺化網頁開發工具

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

MantisBT
Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

禪工作室 13.0.1
強大的PHP整合開發環境