javascript – WebWorkers执行似乎比主线程慢得多

我一直在努力优化一些长期运行的JAvaScript,并尝试实现WebWorkers.

我有一组独立的计算任务.在我的初始测试中有80个任务,并且在主线程上完成250ms.我认为我可以将任务分配给一些网络工作者,并将时间缩短到50毫秒.

我的数据是嵌套多个类型数组的几何数据结构.我有方法将所有数据提取JSON的ArrayBuffer对象数组,因此我可以将数据传递给WebWorker,而无需复制大数组.

>我已经测试了数据传输,并确认它正在按预期工作.传输到WebWorker后,我的Typed数组在主线程中为空.
>我预先启动(现在)4名网络工作人员,这样当需要完成工作时,工作人员应该做好准备.
>当每个工作人员完成一项任务时,我会在队列中为其提供下一个任务,直到队列为空.
>我在Web工作者中跟踪时间,以查看在实际计算中使用了多少(例如忽略数据传输开销).
>我有一台8核笔记本电脑,每天运行多线程代码.

这是我的WebWorker脚本.

importScripts('../lib/MyLib.js');

let timeComputing = 0;  
this.onmessage = function(e) {
  switch (e.data.msg) {
    case 'compute':
        let mesh = ... unpack data;
        let start = performance.Now();
        mesh.doexpensiveCompute();
        timeComputing += performance.Now() - start;
        ... send data back to the main thread.
        break;
    case 'logTime':
        console.log("timeComputing:" + timeComputing);
  }
}

当工人记录使用的时间时,通常每个工人约130ms,这意味着总时间实际上接近500ms.主线程在250ms内完成所有工作,所以使用WebWorkers我会慢100%.出于某种原因,在WebWorker中运行的完全相同的代码比在主线程上运行的代码要慢得多.

我很快就会有一些工作量可能有数百个任务,所以我希望WebWorkers可以保持我的页面响应. (目前它在大负荷下根本没有).

有人会有什么建议,为什么我看到这样糟糕的结果?注意:我已经消除了数据传输的成本(我相信这是最小的)和线程启动.我纯粹是在测量工作人员的计算时间,这很差……有没有人有经验在网络工作者中运行繁重的计算任务?

一个想法是,我的工作脚本也加载我的主引擎脚本. (示例代码中的MyLib.js),这是一个Webpacked脚本,非常大.我使用了这个,所以希望浏览器缓存意味着它不需要再次请求它.也许我应该为webworker上下文生成我的引擎的最小版本.

谢谢你的任何提示……

最佳答案
我现在调试了我的工人.

importScripts(” ../ LIB / MyLib.js’);

最初,我原以为在工作器中重用我的主库js文件会使浏览器使用lib的缓存版本.即浏览器不需要HTTP请求文件,或编译它,因为它已经在内存中.结果证明是错误的,浏览器需要重新请求文件并重新编译它.

因为我的脚本非常大,重新编译成了一个很大的开销,因为它似乎也需要为每个线程重新编译它.我通过测量每项任务的往返时间来得出这个结论,同时在工人中执行零工作.每个线程的往返时间开始非常高(300毫秒),并迅速降至<几次迭代后1ms. 我现在使用内联Web工作者来避免额外请求并保持我的库封装,如下所述:http://www.html5rocks.com/en/tutorials/workers/basics/#toc-inlineworkers
并且还将工作人员的简化脚本用于最低限度.

我现在的表现非常出色.什么是250毫秒~50毫秒.第一次往返很慢,但也不算太糟糕,并且网上工作者的内联使得它变得更快.

相关文章

前言 做过web项目开发的人对layer弹层组件肯定不陌生,作为l...
前言 前端表单校验是过滤无效数据、假数据、有毒数据的第一步...
前言 图片上传是web项目常见的需求,我基于之前的博客的代码...
前言 导出Excel文件这个功能,通常都是在后端实现返回前端一...
前言 众所周知,js是单线程的,从上往下,从左往右依次执行,...
前言 项目开发中,我们可能会碰到这样的需求:select标签,禁...