在我的网站上,我有许多包含数据的数组。 例如:顶点数组、颜色数组、尺寸数组...
我正在处理大量项目。高达数千万。
在将数据添加到数组之前,我需要对其进行处理。 直到现在,我都是在主线程中完成的,这让我的网站卡住了 X 秒。 由于处理以及将处理后的数据添加到数组中,它卡住了。
今天我将处理“移动”(做了很多工作)到 web worker 中,但是处理后的数据被添加到主线程中。我设法节省了处理的卡住时间,但没有节省添加的时间。
添加只需通过 array.push()
或 array.splice()
即可完成。
我读过一些关于数组如何工作的文章,发现当我们将项目添加到数组时,数组被完全复制到内存中的一个新位置 array.length + 1
大小并在那里添加值。这使我的数据推送缓慢。
我还读到类型化数组要快得多。但是为此我需要知道数组的大小,我不知道,并且创建一个带有额外计数器的大类型数组并管理在中间(而不是数组的末尾)添加项目将是一个很多代码更改,我现在不想这样做。
所以,对于我的问题, 我有从网络 worker 返回的 TypedArray,我需要将其放入常规数组中。最好的性能方法是什么? (今天我循环运行,一个接一个地推)
编辑
网站运作方式示例: 客户添加项目数,比如说 100000。 正在收集项目原始数据并将其发送给工作人员。 工作人员正在处理所有信息并将处理后的数据作为类型化数组发回(用作可传输对象)。在主线程中,我们将处理后的数据添加到数组中——添加到末尾或某个特定的索引中。 第二轮。客户再添加 100000 个项目。发送给工作人员并将结果添加到主线程数组。 第 3 轮可以是 10 个项目,第 4 轮 10000,第 5 轮可以删除索引 10-2000,...
最佳答案
使用评论进行了更多研究并思考了另一个方向。
我试过使用 typedArray.set
方法,发现它非常非常快。
使用集合的 1000 万个项目花费了 0.004 秒,而 array.push
为 0.866 秒。我将 1000 万分成 10 个数组,只是为了确保 set 方法在从索引 0 开始时不会工作得更快。
这样我想我什至可以使用 TypedArray 实现我自己的 insertAtIndex
,它将所有项向前推并在正确的索引中设置新项。
此外,我可以使用 TypedArray.subArray
根据数组中的实际数据量(这不是复制数据)获取我的子数据 - 对于将数据上传到缓冲区(WebGL)
我说过我想使用常规数组,但这种性能提升我认为我不会有其他明智的做法。当我使用所有 push
、splice
、自己的实现将 MyNewTypedArray 包装为 TypedArray 时,工作量并不大。
希望这些信息对大家有帮助
var maxCount = 10000000;
var a = new Float32Array(maxCount);
var aSimple = [];
var arrays = [];
var div = 10;
var arrayLen = maxCount / div;
for (var arraysIdx = 0; arraysIdx < div; arraysIdx++) {
var b = new Float32Array(arrayLen);
for (var i = 0; i < b.length; i++) {
b[i] = i * (arraysIdx + 1);
}
arrays.push(b);
}
var timeBefore = new Date().getTime();
for (var currArrayIdx = 0; currArrayIdx < arrays.length; currArrayIdx++) {
a.set(arrays[currArrayIdx], currArrayIdx * arrayLen);
}
var timeAfter = new Date().getTime();
good.innerHTML = (timeAfter - timeBefore) / 1000 + " sec.\n";
timeBefore = new Date().getTime();
for (var currArrayIdx = 0; currArrayIdx < arrays.length; currArrayIdx++) {
for (var i = 0; i < arrayLen; i++) {
aSimple.push(arrays[currArrayIdx][i]);
}
}
timeAfter = new Date().getTime();
bad.innerHTML = (timeAfter - timeBefore) / 1000 + " sec.\n";
Using set of TypedArray:
<div id='good' style='background-color:lightGreen'>working...</div>
Using push of Array:
<div id='bad' style='background-color:red'>working...</div>
关于javascript - 将项目插入数组的最佳性能方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30188970/