iustin96
iustin96

Reputation: 21

Why the web worker version runs longer?

I'm trying to sum up numbers using two different variants, without web workers and using web workers.

I expect the web workers version to be about ten times faster because I divide the interval into ten intervals, but it's not like that. It's about ten times slower. I do not understand why. Does the ten web workers work in parallel?

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

Upvotes: 2

Views: 1055

Answers (1)

Kaiido
Kaiido

Reputation: 137171

There are many things here that could make your observations vary a lot, like how browsers do optimize your code (particularly for such simple for loops), but to answer the general question Why running through Web-Workers takes more time, then ...

  • You are running 10 workers in parallel. If your computer is not able to run ten threads concurrently, all your threads will indeed get slowed down.
    As a rule of thumb, never exceed navigator.hardwareConcurrency- 1 number of concurrent Web Workers on the same page.

  • Initializing a WebWorker is not such a fast operation. It includes a Network request, parsing of the js file, building of the context. So initialize it once, and then ask them multiple times to do what you want.

But note that even then, you'll probably have slower results using the Workers with such a small operation. The simple operation

 worker.postMessage(); // in main
 self.onmessage = e => self.postMessage(); // in worker.js
 worker.onmessage = e => ... // back in main

will already take place in at least 3 different event loops, since messages are received in the event loop following the one they've been sent from. Unless you have some operations that will take seconds, offloading on worker might indeed get slower.

But even if slower, having your job offloaded in Worker allows the main thread to be free, and these 30ms will cause a drop of two frames, which could make something like an animation look jerky, so keep on using WebWorkers, but not for the speed.

Upvotes: 4

Related Questions