我有一个项目,我必须处理相当大的对象,每个对象大约需要 500 毫秒。我认为使用网络 worker 会大大加快这个过程。但在尝试了网络工作人员之后,他们似乎根本没有提高速度 - 即使我取消了网络工作人员创建的预处理。
因此我决定创建一个简单的示例:有一个包含 N
个数字的数组,并且应该计算这些数字的总和。
首先,没有网络 worker ( 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];
}
然后,与网络 worker ( 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
}
所以结果是:网络 worker 似乎完全是灾难性的。比没有网络 worker 的情况下慢 10 倍以上。
所以我的问题是,任何人都可以向我展示一个例子,其中网络 worker 的多线程实际上更快吗?除了在不影响 UI 的情况下运行之外,我看不到网络 worker 的意义......
编辑:它的运行速度要慢得多,但 CPU 使用率要高得多(使用网络 worker 时为 100%,不使用网络 worker 时约 30%) - 这让我怀疑所有这些功能都去哪儿了
编辑2:即使当你将onmessage
留在工作端时什么都不做,它仍然运行得更慢......看起来像是主线程之间的通信并且工作线程非常慢( see for yourself )
编辑3:它与postMessage
无关,我已经测量了性能,并且我无法通过不同的编码来解决这个问题。最奇怪的事情是:当我使用 Google Chrome 开发工具测量性能时,它的运行速度几乎是原来的 2 倍
有趣article :
最佳答案
您的基准因向每个工作人员传输一千万个号码的成本而被淹没。
相反,创建一个ArrayBuffer
。将其作为 transferList
的一部分(postMessage
的第二个参数)传递。在我的机器上,worker 运行这项工作的时间不到 100 毫秒,而没有worker 则需要 200 毫秒。
关于javascript - webworkers 的多线程效率低下吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44808354/