javascript - 将项目插入数组的最佳性能方法?

标签 javascript arrays multithreading web-worker typed-arrays

在我的网站上,我有许多包含数据的数组。 例如:顶点数组、颜色数组、尺寸数组...

我正在处理大量项目。高达数千万。

在将数据添加到数组之前,我需要对其进行处理。 直到现在,我都是在主线程中完成的,这让我的网站卡住了 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)

我说过我想使用常规数组,但这种性能提升我认为我不会有其他明智的做法。当我使用所有 pushsplice、自己的实现将 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/

相关文章:

java - 如何检测另一个java线程是否被挂起或卡住?

javascript - Primefaces GMap Overlay Select 事件并在单击时弹出输出面板

javascript - 主干(同步)更新事件

javascript - 无法识别外部 JS 函数

java - 重复数组的元素

c - 为字符数组的strlen分配空间时为什么要加1?

javascript - 如何使用 webpack 请求 jquery

c++ - 删除 char*[] 中的第一个索引

java - 在 Java 中等待多个线程完成

c++ - 基于 Qt 的 CD 开膛手的线程构建 block (TBB)?