Почему версия веб-работника работает дольше? - PullRequest
0 голосов
/ 06 января 2019

Я пытаюсь суммировать числа, используя два разных варианта, без веб-работников и веб-работников.

Я ожидаю, что версия для веб-работников будет примерно в десять раз быстрее, потому что я делю интервал на десять интервалов, но это не так. Это примерно в десять раз медленнее. Я не понимаю почему. Работают ли десять веб-работников параллельно?

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 голосов
/ 06 января 2019

Здесь есть много вещей, которые могут сильно изменить ваши наблюдения, например, как браузеры оптимизируют ваш код (особенно для таких простых циклов for), но чтобы ответить на общий вопрос Почему для работы через Web-Workers требуется больше время , затем ...

  • Вы работаете 10 рабочих параллельно. Если ваш компьютер не может запускать десять потоков одновременно, все ваши потоки действительно замедляются.
    Как правило, никогда не превышайте navigator.hardwareConcurrency- 1 количество одновременных веб-работников на одной странице.

  • Инициализация WebWorker не такая быстрая операция. Он включает в себя сетевой запрос, разбор js-файла, построение контекста. Так что инициализируйте его один раз, а затем попросите их сделать то, что вы хотите, несколько раз.

Но учтите, что даже тогда вы, вероятно, получите более медленные результаты при использовании Workers с такой маленькой операцией. Простая операция

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

уже будет происходить как минимум в 3 различных циклах событий, поскольку сообщения принимаются в цикле событий после того, из которого они были отправлены. Если у вас нет некоторых операций, которые займут секунды, разгрузка на рабочем месте может действительно замедлиться.

Но даже если это происходит медленнее, выгрузка вашей работы в Worker позволяет освободить основной поток, и эти 30 мс вызовут выпадение двух кадров, что может сделать анимацию похожей на рывок, поэтому продолжайте использовать WebWorkers, но не для скорости.

...