我有一个项目,我必须处理相当大的物体,每个物体大约需要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:
答案 0 :(得分:4)
你的基准正在被向每个工人转移一千万个号码的成本所淹没。
而是创建一个ArrayBuffer
。将其作为transferList
(postMessage
的第二个参数)的一部分传递。在我的机器上,工人在不到100毫秒的时间内完成这项工作,而没有工人的工作时间为200毫秒。