处理大型数组时的JavaScript性能

处理大型数组时的JavaScript性能,javascript,html,performance,image-processing,web-worker,Javascript,Html,Performance,Image Processing,Web Worker,我目前正在用JavaScript编写一个图像编辑程序。我选择JS是因为我想了解更多。我处理的平均图像约为3000 x 4000像素。当转换为imageData(用于编辑像素)时,我需要处理的值总计为48000000。这就是为什么我决定引入webworkers,让他们只编辑数组的第n部分。假设我有十个webworker,每个worker必须处理4800000个值。 为了能够使用webworkers,我将大数组除以我选择的线程数量。我使用的代码如下所示: while(pixelArray.lengt

我目前正在用JavaScript编写一个图像编辑程序。我选择JS是因为我想了解更多。我处理的平均图像约为3000 x 4000像素。当转换为imageData(用于编辑像素)时,我需要处理的值总计为48000000。这就是为什么我决定引入webworkers,让他们只编辑数组的第n部分。假设我有十个webworker,每个worker必须处理4800000个值。 为了能够使用webworkers,我将大数组除以我选择的线程数量。我使用的代码如下所示:

while(pixelArray.length > 0){
    cD.pixelsSliced.push(pixelArray.splice(0, chunks)); //Chop off a chunk from the picture array
}
稍后,在工作人员对该数组执行某些操作后,他们将其保存到另一个数组中。每个工作人员都有一个ID,并将其部分保存在其ID所在的数组中(以确保数组保持正确的顺序)。我使用$.map将该数组(看起来像[[1231][123213123][213123123]]合并到一个大数组[231231413431]中,稍后我将从中创建所需的imageData。它看起来像:

cD.newPixels = jQuery.map(pixelsnew, function(n){
    return n;
});
创建此阵列(cD.pixelsliced)后,我创建imageData并将此图像复制到imageData对象中,如下所示:

cD.imageData = cD.context.createImageData(cD.width, cD.height);
for(var i = 0; i < cD.imageData.data.length; i +=4){ //Build imageData
    cD.imageData.data[i + eD.offset["r"]] = cD.newPixels[i + eD.offset["r"]];
    cD.imageData.data[i + eD.offset["g"]] = cD.newPixels[i + eD.offset["g"]];
    cD.imageData.data[i + eD.offset["b"]] = cD.newPixels[i + eD.offset["b"]];
    cD.imageData.data[i + eD.offset["a"]] = cD.newPixels[i + eD.offset["a"]];
}
cD.imageData=cD.context.createImageData(cD.width,cD.height);
对于(var i=0;i
现在我意识到我正在处理大量的数据,我可能不应该使用浏览器进行图像编辑,而是使用另一种语言(我在uni中使用Java)但是,我想知道您是否有关于性能的建议,因为坦率地说,当我第一次尝试大映像时,我感到非常惊讶。我没有想到,加载映像需要“那么”长的时间(代码的第一次和平).Firefox实际上认为我的脚本坏了。代码的其他两部分是那些我发现会减慢脚本速度的部分(这是正常的)。所以,是的,如果有任何提示,我将不胜感激


谢谢

我建议在使用Web Workers时使用可转移对象,而不是结构化克隆。Web Workers通常使用结构化克隆传递对象,换句话说,复制对象。对于大型对象(如大型图像),这可能需要大量时间

当使用可转移对象时,数据从一个上下文转移到另一个上下文。换句话说,零拷贝,这将提高向工作者发送数据的性能

有关更多信息,请查看:

另外,另一个想法可能是将拆分和对接大型阵列的任务转移给web工作者。 在这里进行头脑风暴,但是,也许你可以先创建一个Web工作人员,我们称之为母工作人员。这个工作人员可以拆分阵列,然后生成10个其他子工作人员来执行繁重的任务并发送回他们的母亲


母亲最终将所有内容放回一起并发送回主应用程序。

不要在包含4800万项的数组上使用“jQuery.map”之类的东西。这太荒谬了。另外,忘记web工作者吧,因为他们不仅需要复制,还需要序列化。直接在主/ui中循环数组会快10000x请阅读。以150毫秒为例,将每个值增加1。将该数组序列化为json只需将其传递给web Worker需要几年时间。我建议使用jsperf.com对您的变体进行性能调优和测试