优化:将多维数组拆分为子数组

时间:2017-03-08 23:49:03

标签: javascript arrays optimization multidimensional-array

我有一个多维数组,由以下格式组成:

var source = [['Item 1', 10],['Item 2', 15],['Item 3', 50],['Item 4', 25]];

这包含两个并行数据集:source[x][0]是数据,source[x][1]是应用于每个数据项的权重。我发现自己处于需要将其拆分为组件数组,数据和权重的位置。我可以(并且目前)以下列方式执行此操作:

var weighting = [], data = [];
for (var index = 0; index < source.length; index++)
{
    data.push(source[index][0]);
    weighting.push(source[index][1]);
}

这导致我拥有以下两个数组(继续前面的示例):

var data = ['Item 1', 'Item 2', 'Item 3', 'Item 4'];
var weighting = [10, 15, 50, 25];

有更快的方法吗?我正在使用的源数组包含大约200万套数据和权重,因此比一次将一个条目分开的循环更便宜的代价可以显着节省CPU时间。

2 个答案:

答案 0 :(得分:1)

这是一种Code Review问题,因为此解决方案可以正常运行和运行。你最感兴趣的是表现。

现在给出一个for循环通常会胜过其他任何解决方案。但是,您可以稍微提高性能。

  • 在循环中缓存数组的长度变量,防止必须继续检查长度。
  • 在循环中检索索引对,而不是两次引用它。

以下是一个例子:

var source = [
  ['Item 1', 10],
  ['Item 2', 15],
  ['Item 3', 50],
  ['Item 4', 25]
];

var data = [],
  weightings = [];

for (var i = 0, l = source.length; i < l; i++) {
  var item = source[i];
  data.push(item[0]);
  weightings.push(item[1])
}

console.log(data);
console.log(weightings);

根据for循环中的示例,我们将l的值分配给数组的长度。到var i = 0, l = source.length;现在,这在循环的持续时间内被有效地缓存。

接下来,我们在循环var item = source[i];中检索了索引对(数组),因此我们不必在数组中找到它两次。

可以在jsPerf: Reduce vs. Loop 12上测试。

现在实际上有2,000,000条记录,orignal方法不需要太多时间(我的测试机器上大约100毫秒)。

这是一个测试示例,检查控制台的时间非常接近。

JSFiddle

效果评估

机器(i7 5820k 64 GB DDR4 RAM): 注意我已经更新了小提琴,只是出于感兴趣而包含while版本。

Old Version took 83.56999999999994 ms
Perf Version took 44.24500000000012 ms
While took 76.2800000000002 ms

对我而言,这是 ~45%的增加,是的,这只是一个很小的时间差异。

答案 1 :(得分:0)

此函数只查看数组中的每个项目,并将各个属性推送到新数组中。底部的两个循环是不必要的。我把它们放在那里查看结果。

var source = [['Item 1', 10],['Item 2', 15],['Item 3', 50],['Item 4', 25]];
var arr1 = [];
var arr2 = [];

splitArray();

function splitArray() {
  for (var i = 0; i < source.length; i++) {
    var item = source[i];
    arr1.push(item[0]);
    arr2.push(item[1]);
  }

  for(var j = 0; j < arr1.length; j++) {
    console.log(arr1[j]);
  }

  for(var k = 0; k < arr1.length; k++) {
    console.log(arr2[k]);
  }
}