搜索
首页web前端js教程并联JavaScript
并联JavaScriptFeb 18, 2025 am 08:51 AM

ParallelJS:优雅的Web Worker解决方案

ParallelJS为使用Web Worker时可能出现的问题提供了一种优雅的解决方案,它提供了一个具有便捷抽象和辅助工具的实用API。HTML5引入的Worker接口允许创建具有较长运行时间和高计算量需求的函数,这些函数可以同时使用以提高网站响应速度。ParallelJS允许对JavaScript代码进行并行化处理,利用同时多线程 (SMT) 更有效地使用现代CPU。ParallelJS库提供诸如spawnmapreduce等方法,分别用于并行执行计算、处理数据和聚合碎片化结果。

HTML5带来的一个最酷的新可能性是Web Workers API的Worker接口。在此之前,我们不得不采用一些技巧来向用户展示响应迅速的网站。Worker接口允许我们创建具有较长运行时间和高计算量需求的函数。此外,Worker实例可以同时使用,使我们能够根据需要生成任意数量的这些工作器。在本文中,我将讨论为什么多线程很重要,以及如何使用ParallelJS在JavaScript中实现它。

为什么需要多线程?

这是一个合理的问题。从历史上看,生成线程的能力提供了一种优雅的方式来划分进程中的工作。操作系统负责调度每个线程的可用时间,这样优先级更高、工作量更大的线程将优先于低优先级的空闲线程。在过去的几年里,同时多线程 (SMT) 已经成为访问现代CPU计算能力的关键。原因很简单:摩尔定律在每单位面积晶体管数量方面仍然有效。然而,由于多种原因,频率缩放不得不停止。因此,必须以其他方式使用可用的晶体管。人们决定,架构改进(例如SIMD)和多核代表最佳选择。

Parallel JavaScript with ParallelJS

为了使用SMT,我们需要编写并行代码,即为获得单个结果而并行运行的代码。我们通常需要考虑特殊的算法,因为大多数顺序代码要么很难并行化,要么效率非常低。原因在于Amdahl定律,该定律指出加速比S由下式给出:

Parallel JavaScript with ParallelJS

其中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中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
在JavaScript中替换字符串字符在JavaScript中替换字符串字符Mar 11, 2025 am 12:07 AM

JavaScript字符串替换方法详解及常见问题解答 本文将探讨两种在JavaScript中替换字符串字符的方法:在JavaScript代码内部替换和在网页HTML内部替换。 在JavaScript代码内部替换字符串 最直接的方法是使用replace()方法: str = str.replace("find","replace"); 该方法仅替换第一个匹配项。要替换所有匹配项,需使用正则表达式并添加全局标志g: str = str.replace(/fi

自定义Google搜索API设置教程自定义Google搜索API设置教程Mar 04, 2025 am 01:06 AM

本教程向您展示了如何将自定义的Google搜索API集成到您的博客或网站中,提供了比标准WordPress主题搜索功能更精致的搜索体验。 令人惊讶的是简单!您将能够将搜索限制为Y

构建您自己的Ajax Web应用程序构建您自己的Ajax Web应用程序Mar 09, 2025 am 12:11 AM

因此,在这里,您准备好了解所有称为Ajax的东西。但是,到底是什么? AJAX一词是指用于创建动态,交互式Web内容的一系列宽松的技术。 Ajax一词,最初由Jesse J创造

示例颜色json文件示例颜色json文件Mar 03, 2025 am 12:35 AM

本文系列在2017年中期进行了最新信息和新示例。 在此JSON示例中,我们将研究如何使用JSON格式将简单值存储在文件中。 使用键值对符号,我们可以存储任何类型的

8令人惊叹的jQuery页面布局插件8令人惊叹的jQuery页面布局插件Mar 06, 2025 am 12:48 AM

利用轻松的网页布局:8个基本插件 jQuery大大简化了网页布局。 本文重点介绍了简化该过程的八个功能强大的JQuery插件,对于手动网站创建特别有用

什么是这个&#x27;在JavaScript?什么是这个&#x27;在JavaScript?Mar 04, 2025 am 01:15 AM

核心要点 JavaScript 中的 this 通常指代“拥有”该方法的对象,但具体取决于函数的调用方式。 没有当前对象时,this 指代全局对象。在 Web 浏览器中,它由 window 表示。 调用函数时,this 保持全局对象;但调用对象构造函数或其任何方法时,this 指代对象的实例。 可以使用 call()、apply() 和 bind() 等方法更改 this 的上下文。这些方法使用给定的 this 值和参数调用函数。 JavaScript 是一门优秀的编程语言。几年前,这句话可

通过来源查看器提高您的jQuery知识通过来源查看器提高您的jQuery知识Mar 05, 2025 am 12:54 AM

jQuery是一个很棒的JavaScript框架。但是,与任何图书馆一样,有时有必要在引擎盖下发现发生了什么。也许是因为您正在追踪一个错误,或者只是对jQuery如何实现特定UI感到好奇

10张移动秘籍用于移动开发10张移动秘籍用于移动开发Mar 05, 2025 am 12:43 AM

该帖子编写了有用的作弊表,参考指南,快速食谱以及用于Android,BlackBerry和iPhone应用程序开发的代码片段。 没有开发人员应该没有他们! 触摸手势参考指南(PDF) Desig的宝贵资源

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
2 周前By尊渡假赌尊渡假赌尊渡假赌
仓库:如何复兴队友
1 个月前By尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒险:如何获得巨型种子
4 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

mPDF

mPDF

mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )专业的PHP集成开发工具

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具