我正在尝试使用两个不同的变量来求和,而不使用网络工作者,而使用网络工作者。
我希望Web Worker版本快大约十倍,因为我将间隔分为十个间隔,但事实并非如此。它慢了大约十倍。我不懂为什么。十个网络工作者可以并行工作吗?
var sum1 = 0, sum2 = 0, nrElements = 10000000;
var t0 = performance.now();
for (var i=0; i < nrElements; i++) {
sum1 += i;
}
var t1 = performance.now();
console.log("Version1 - " + (t1 - t0) + " sum: " + sum1)
var t3 = performance.now();
var n, running;
var pas = 0;
running = 0;
for (n = 0; n < 10; ++n) {
let workers = new Worker("worker.js");
pozStart = pas;
pas += nrElements / 10;
pozStop = pas;
workers.postMessage({start: pozStart, stop: pozStop});
workers.onmessage = workerDone;
++running;
}
function workerDone(e) {
--running;
sum2 += e.data[1];
if (running === 0) {
var t4 = performance.now();
console.log("Version2 - " + (t4 - t3) + " sum: " + sum2)
}
}
//worker.js
onmessage = function(e) {
var sum=0;
for(let i= e.data.start; i < e.data.stop; i++)
{
sum += i;
}
postMessage(["r",sum]);
}
答案 0 :(得分:2)
这里有很多事情可以使您的观察结果变化很大,例如浏览器如何优化代码(尤其是对于如此简单的for循环),但要回答一般性问题为什么通过Web-Workers运行需要更多时间时间,然后...
您正在并行运行10个工作程序。如果您的计算机不能同时运行十个线程,则所有线程的确会变慢。
根据经验,在同一页面上并发Web Worker的数量绝不能超过navigator.hardwareConcurrency
- 1
。
初始化WebWorker并不是这么快的操作。它包括一个网络请求,js文件的解析,上下文的构建。因此,将其初始化一次,然后多次要求他们执行您想要的操作。
但是请注意,即使那样,使用工人进行如此小的操作也可能会导致结果变慢。简单的操作
worker.postMessage(); // in main
self.onmessage = e => self.postMessage(); // in worker.js
worker.onmessage = e => ... // back in main
将已经在至少3个不同的事件循环中发生,因为消息是在发送消息的消息之后在事件循环中接收到的。 除非您有一些操作需要几秒钟的时间,否则工作人员的卸载确实确实会变慢。
但是,即使速度较慢,将工作分担到Worker中也可以使主线程空闲,并且这30ms将导致丢掉两帧,这可能会使动画看起来有些生涩,因此请继续使用WebWorkers,但是不是为了速度。