处理大型数组时的JavaScript性能

JavaScript performance when handling large arrays

本文关键字:JavaScript 性能 大型 数组 处理      更新时间:2023-09-26

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

while(pixelArray.length > 0){
    cD.pixelsSliced.push(pixelArray.splice(0, chunks)); //Chop off a chunk from the picture array
}

稍后,在工作人员对数组执行某些操作后,他们将其保存到另一个数组中。每个工作人员都有一个ID,并将其部分保存在上述数组中ID所在的位置(以确保数组保持正确的顺序)。我使用$.map将该数组(看起来像[[1231][12321123][213123123]])连接到一个大数组[2231231231413431]中,稍后我将从中创建我需要的imageData

cD.newPixels = jQuery.map(pixelsnew, function(n){
    return n;
});

创建这个数组(cD.pixelsSliced)后,我创建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"]];
}

现在我意识到我在这里处理大量的数据,我可能不应该使用浏览器进行图像编辑,而是使用不同的语言(我在大学里使用Java)。然而,我想知道你是否有关于表演的建议,因为坦率地说,当我第一次尝试大图像时,我非常惊讶。我没想到,加载图像需要"那么"长的时间(代码的第一次平静)。Firefox实际上认为我的脚本坏了。代码的另外两部分是我发现会减慢脚本速度的部分(这很正常)。所以,是的,我会感谢任何提示。

感谢

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

使用可传输对象时,数据会从一个上下文传输到另一个上下文。换句话说,零拷贝,这将提高向Worker发送数据的性能。

有关更多信息,请查看:http://www.w3.org/html/wg/drafts/html/master/infrastructure.html#transferable-对象

另外,另一个想法可能是将拆分和对接大型数组的任务转移到web工作者身上。只是头脑风暴,但是,也许你可以先创建一个网络工作者,让我们称之为母亲工作者。这个工人可以分割阵列,然后产生10个其他童工,执行繁重的任务并送回他们的母亲。

母亲终于把所有的东西放回了一起,并把它们送回了主应用程序。