javascript - 创建 Javascript 数组的不同方法

标签 javascript arrays performance

我想了解构造数组的性能差异。运行以下程序,我对下面的输出感到困惑:

Time for range0: 521
Time for range1: 149
Time for range2: 1848
Time for range3: 8411
Time for range4: 3487

我不明白为什么 3 比 4 需要更长的时间,而 1 比 2 更短。而且,map 函数似乎效率很低;它有什么用?

<小时/>

function range0(start, count) {
    var arr = [];
    for (var i = 0; i < count; i++) {
        arr.push(start + i);
    }
    return arr;
}

function range1(start, count) {
    var arr = new Array(count);
    for (var i = 0; i < count; i++) {
        arr[i] = start + i;
    }
    return arr;
}

function range2(start, count) {
    var arr = Array.apply(0, Array(count));
    for (var i = 0; i < count; i++) {
        arr[i] = start + i;
    }
    return arr;
}

function range3(start, count) {
    var arr = new Array(count);
    return arr.map(function(element, index) {
        return index + start;
    });
}

function range4(start, count) {
    var arr = Array.apply(0, Array(count));
    return arr.map(function(element, index) {
        return index + start;
    });
}

function profile(range) {
    var iterations = 100000,
        start = 0, count = 1000,
        startTime, endTime, finalTime;

    startTime = performance.now();

    for (var i = 0; i < iterations; ++i) {
        range(start, count);
    }

    endTime = performance.now();

    finalTime = (endTime - startTime);
    console.log(range.name + ': ' + finalTime + ' ms');
}

[range0, range1, range2, range3, range4].forEach(profile);

最佳答案

I don't understand why 3 takes longer than 4

我也没有。考虑到我的肤浅分析和通过分析代码获得的结果,这是一个令人惊讶的结果。在我运行 Google Chrome 50 的计算机上,range4 的速度是 range3 的两倍。

我必须研究您正在使用的 Javascript 实现才能找出发生这种情况的原因。

while 1 takes shorter than 2.

range1 执行速度更快,因为它使用循环并优化内存分配,而 range2 使用函数并执行不必要的内存分配。

Also, seems the map function is very inefficient; what is the use of it?

map函数用于根据现有数组的值计算新的数组

[1, 2, 3, 4, 5].map(number => number * number);
// [1, 4, 9, 16, 25]
<小时/>

在我的计算机上

Time for range0: 783
Time for range1: 287
Time for range2: 10541
Time for range3: 14981
Time for range4: 28243

我的结果反射(reflect)了我对每个功能的性能的期望。

各个功能浅析

  • 范围0

    创建 Array并通过循环填充它。这是最简单、最直接的代码。我想它可以被理解为性能比较的基线

  • 范围1

    使用Array constructor带长度参数。这极大地优化了存储元素所需的底层内存分配。由于元素的确切数量事先已知,因此内存不必是 realloc随着元素数量的增加而增加;当 Array 时,存储所有元素所需的确切内存量可以被分配一次。已实例化。

  • 范围2

    Applies构造函数的参数列表,其中this设置为数字0。这在语义上等同于 Array() – 事实上,参数列表是使用 count 参数创建的,这对函数应用程序的结果没有影响。事实上,它不必要地浪费时间为参数列表分配内存。

    您可能想使用 call :

      Array.call(null, count)
    
  • 范围3

    range1类似,但使用map用函数而不是循环。初始内存分配已优化,但调用函数 count 次的开销可能会很大。

    此外,map生成一个新的 Array实例。由于该实例也有 count 元素,因此优化该内存分配也是有意义的,但我不清楚这是否真的发生。尽管如此,还是发生了两次单独的内存分配,而不是像 range1 中那样只进行一次。

  • 范围4

    结合了 range2range3 的所有低效之处。

    令人惊讶的是,它在计算机上的执行速度比 range3 还要快。我不清楚为什么会发生这种情况。我想人们必须研究你的 Javascript 特定实现才能弄清楚。

关于javascript - 创建 Javascript 数组的不同方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37557135/

相关文章:

javascript - 通过 exec 将变量传递给 PhantomJS

java - 可执行 Jars 运行非常缓慢

php - 具有多个连接的 SQL 查询会影响性能

javascript - 不可变的 js : make a function more. 。功能性的

javascript - 如何检测表中动态行的列中的值变化?

c++ - 在 C++ 中将 vector<string> 转换为 unsigned char 数组

javascript - 为什么 Ractive.js 的 reset() 和 update() 方法在有一个带有 array.prototype.sort() 的助手和一个空对象的数据时复制模板

java - 降雨量类别,从数组中查找最大值和最小值

c# - ConcurrentDictionary.Where 对于基于 int 数组(键字段)的过滤非常慢

javascript - 数据表在更改事件时重新加载