为什么Web Worker版本运行时间更长?

时间:2019-01-05 23:59:31

标签: javascript web-worker

我正在尝试使用两个不同的变量来求和,而不使用网络工作者,而使用网络工作者。

我希望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]);
}

1 个答案:

答案 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,但是不是为了速度。