Phi*_*lor 7 javascript performance web-worker
我一直在努力优化一些长期运行的JAvaScript,并尝试实现WebWorkers.
我有一组独立的计算任务.在我的初始测试中有80个任务,并且在主线程上完成250ms.我认为我可以将任务分配给一些网络工作者,并将时间缩短到50毫秒.
我的数据是嵌套多个类型数组的几何数据结构.我有方法将所有数据提取到JSON +一个ArrayBuffer对象数组,因此我可以将数据传递给WebWorker,而无需复制大数组.
这是我的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);
}
}
Run Code Online (Sandbox Code Playgroud)
当工人记录使用的时间时,通常每个工人约130ms,这意味着总时间实际上接近500ms.主线程在250ms内完成所有工作,所以使用WebWorkers我会慢100%.出于某种原因,在WebWorker中运行的完全相同的代码比在主线程上运行的代码要慢得多.
我很快就会有一些工作量可能有数百个任务,所以我希望WebWorkers可以保持我的页面响应.(目前它在大负荷下根本没有).
有人会有什么建议,为什么我看到这样糟糕的结果?注意:我已经消除了数据传输的成本(我相信这是最小的)和线程启动.我纯粹是在测量工作人员的计算时间,这很差......有没有人有经验在网络工作者中运行繁重的计算任务?
一个想法是,我的工作脚本也加载我的主引擎脚本.(示例代码中的MyLib.js),这是一个Webpacked脚本,非常大.我使用了这个,所以希望浏览器缓存意味着它不需要再次请求它.也许我应该为webworker上下文生成我的引擎的最小版本.
谢谢你的任何提示......
我现在已经调试了我的 Worker。
importScripts('../lib/MyLib.js');
最初,我认为在 worker 中重新使用我的主库 js 文件将使浏览器能够使用缓存版本的 lib。即浏览器不需要 HTTP 请求文件或编译它,因为它已经在内存中。结果证明这是错误的,浏览器需要重新请求文件并重新编译它。
因为我的脚本非常大,重新编译成为一个很大的开销,因为它似乎还需要为每个线程重新编译它。我通过测量每项任务的往返时间得出这个结论,同时在工作人员中执行零工作。每个线程的往返时间开始时非常长(300 毫秒),并在几次迭代后迅速下降到 < 1 毫秒。
我现在使用内联 Web Worker 来避免额外的请求并保持我的库封装,如下所述:http : //www.html5rocks.com/en/tutorials/workers/basics/#toc-inlineworkers 并且还使用缩减脚本工人的最低限度。
我现在表现出色。大约 50 毫秒,相当于 250 毫秒。第一次往返很慢,但还不错,内联 Web Worker 让它快了很多。