与webworkers的多线程无效吗?

时间:2017-06-28 16:46:27

标签: javascript web-worker

我有一个项目,我必须处理相当大的物体,每个物体大约需要500毫秒。我认为使用网络工作者会大大加快这个过程。但是在与网络工作者玩耍之后,他们似乎根本没有提高速度 - 即使我把预处理工作带走了网络工作者的创建。

所以我决定创建一个简单的例子:有一个数字N的数组,应该计算这些数字的总和。

首先,没有网络工作者(DEMO):

/** Goal: return sum of all numbers in array */
var numbers = [];

for(var i = 0; i < N; i++){
    numbers.push(Math.floor(Math.random() * 100));
}

/** Test without web workers */
var total = 0;
for(var i = 0; i < numbers.length; i++){
    total += numbers[i];
}

然后, webworkers(DEMO):

/** Options */
var WORKERS = 5; // N should be divisble by WORKERS

/** Test WITH web workers */
var workers = [];

var source = `
onmessage = function(e) {
    var total = 0;
    for(var i = 0; i < e.data.length; i++){
    total += e.data[i];
  }
    postMessage(total);
}`

for(var i = 0; i < WORKERS; i++){
  var blob = new Blob([source]);
  var blobURL = window.URL.createObjectURL(blob);
  let worker = new Worker(blobURL);

  worker.onmessage = function(e){
    total += e.data;
    worker.terminate();
    if(++finished == workers.length) done();
  }

  workers.push(worker);
}

var finished = 0;
var chunk = Math.floor(N / WORKERS);

var sliced = [];
for(var i = 0; i < workers.length; i++){
    sliced.push(numbers.slice(i*chunk,i*chunk+chunk));
}

// we calculate time after we created the workers, from here
var total = 0;
for(var i = 0; i < workers.length; i++){
  workers[i].postMessage(sliced[i]);
}

function done(){
  // do something
}

结果是:网络工作者似乎完全是灾难性的。它比没有网络工作者的速度慢10倍。

所以我的问题是,有人能告诉我一个例子,网络工作者的多线程实际上更快吗?我没有看到网络工作者的意思,除了在不影响用户界面的情况下运行....

编辑:它运行速度较慢,但​​CPU使用率更高(100%,没有网络工作者约30%) - 这让我怀疑所有权力的来源

编辑2:即使你离开工作室onmessage什么都不做,它仍然运行得慢......它似乎是主线程与工作者之间的通信线程速度非常慢(see for yourself

编辑3 它与postMessage无关,我已经衡量了表现,而且通过不同的编码我无能为力。最奇怪的是:当我使用Google Chrome开发工具测量性能时,它的运行速度几乎快了2倍

有趣的article

1 个答案:

答案 0 :(得分:4)

你的基准正在被向每个工人转移一千万个号码的成本所淹没。

而是创建一个ArrayBuffer。将其作为transferListpostMessage的第二个参数)的一部分传递。在我的机器上,工人在不到100毫秒的时间内完成这项工作,而没有工人的工作时间为200毫秒。

请参阅https://jsfiddle.net/ooduhb5h/7/