Most efficient way to create a zero filled JavaScript array?

前端 未结 30 1192
花落未央
花落未央 2020-11-22 05:58

What is the most efficient way to create an arbitrary length zero filled array in JavaScript?

相关标签:
30条回答
  • 2020-11-22 06:11

    If you use ES6, you can use Array.from() like this:

    Array.from({ length: 3 }, () => 0);
    //[0, 0, 0]
    

    Has the same result as

    Array.from({ length: 3 }).map(() => 0)
    //[0, 0, 0]
    

    Because

    Array.from({ length: 3 })
    //[undefined, undefined, undefined]
    
    0 讨论(0)
  • 2020-11-22 06:12

    let filled = [];
    filled.length = 10;
    filled.fill(0);
    
    console.log(filled);

    0 讨论(0)
  • 2020-11-22 06:13

    Shortest for loop code

    a=i=[];for(;i<100;)a[i++]=0;
    
    edit:
    for(a=i=[];i<100;)a[i++]=0;
    or
    for(a=[],i=100;i--;)a[i]=0;
    

    Safe var version

    var a=[],i=0;for(;i<100;)a[i++]=0;
    
    edit:
    for(var i=100,a=[];i--;)a[i]=0;
    
    0 讨论(0)
  • 2020-11-22 06:14

    In short

    Fastest solution

    let a = new Array(n); for (let i=0; i<n; ++i) a[i] = 0;

    Shortest (handy) solution (3x slower for small arrays, slightly slower for big (slowest on Firefox))

    Array(n).fill(0)


    Details

    Today 2020.06.09 I perform tests on macOS High Sierra 10.13.6 on browsers Chrome 83.0, Firefox 77.0, and Safari 13.1. I test chosen solutions for two test cases

    • small array - with 10 elements - you can perform test HERE
    • big arrays - with 1M elements - you can perform test HERE

    Conclusions

    • solution based on new Array(n)+for (N) is fastest solution for small arrays and big arrays (except Chrome but still very fast there) and it is recommended as fast cross-browser solution
    • solution based on new Float32Array(n) (I) returns non typical array (e.g. you cannot call push(..) on it) so I not compare its results with other solutions - however this solution is about 10-20x faster than other solutions for big arrays on all browsers
    • solutions based on for (L,M,N,O) are fast for small arrays
    • solutions based on fill (B,C) are fast on Chrome and Safari but surprisingly slowest on Firefox for big arrays. They are medium fast for small arrays
    • solution based on Array.apply (P) throws error for big arrays
      function P(n) {
        return Array.apply(null, Array(n)).map(Number.prototype.valueOf,0);
      }
      
      
      try {
        P(1000000);
      } catch(e) { 
        console.error(e.message);
      }

    Code and example

    Below code presents solutions used in measurements

    function A(n) {
      return [...new Array(n)].fill(0);
    }
    
    function B(n) {
      return new Array(n).fill(0);
    }
    
    function C(n) {
      return Array(n).fill(0);
    }
    
    function D(n) {
      return Array.from({length: n}, () => 0);
    }
    
    function E(n) {
      return [...new Array(n)].map(x => 0);
    }
    
    // arrays with type
    
    function F(n) {
      return Array.from(new Int32Array(n));
    }
    
    function G(n) {
      return Array.from(new Float32Array(n));
    }
    
    function H(n) {
      return Array.from(new Float64Array(n)); // needs 2x more memory than float32
    }
    
    function I(n) {
      return new Float32Array(n); // this is not typical array
    }
    
    function J(n) {
      return [].slice.apply(new Float32Array(n));
    }
    
    // Based on for
    
    function K(n) {
      let a = [];
      a.length = n;
      let i = 0;
      while (i < n) {
        a[i] = 0;
        i++;
      }
      return a;
    }
    
    function L(n) {
      let a=[]; for(let i=0; i<n; i++) a[i]=0;
      return a;
    }
    
    function M(n) {
      let a=[]; for(let i=0; i<n; i++) a.push(0);
      return a;
    }
    
    function N(n) {
      let a = new Array(n); for (let i=0; i<n; ++i) a[i] = 0;
      return a;
    }
    
    function O(n) {
      let a = new Array(n); for (let i=n; i--;) a[i] = 0;
      return a;
    }
    
    // other
    
    function P(n) {
      return Array.apply(null, Array(n)).map(Number.prototype.valueOf,0);
    }
    
    function Q(n) {
      return "0".repeat( n ).split("").map( parseFloat );
    }
    
    function R(n) {
      return new Array(n+1).join('0').split('').map(parseFloat)
    }
    
    
    // ---------
    // TEST
    // ---------
    
    [A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R].forEach(f => {
      let a = f(10); 
      console.log(`${f.name} length=${a.length}, arr[0]=${a[0]}, arr[9]=${a[9]}`)
    });
    This snippets only present used codes

    Example results for Chrome

    0 讨论(0)
  • 2020-11-22 06:16
    function makeArrayOf(value, length) {
      var arr = [], i = length;
      while (i--) {
        arr[i] = value;
      }
      return arr;
    }
    
    makeArrayOf(0, 5); // [0, 0, 0, 0, 0]
    
    makeArrayOf('x', 3); // ['x', 'x', 'x']
    

    Note that while is usually more efficient than for-in, forEach, etc.

    0 讨论(0)
  • 2020-11-22 06:16

    As of ECMAScript2016, there is one clear choice for large arrays.

    Since this answer still shows up near the top on google searches, here's an answer for 2017.

    Here's a current jsbench with a few dozen popular methods, including many proposed up to now on this question. If you find a better method please add, fork and share.

    I want to note that there is no true most efficient way to create an arbitrary length zero filled array. You can optimize for speed, or for clarity and maintainability - either can be considered the more efficient choice depending on the needs of the project.

    When optimizing for speed, you want to: create the array using literal syntax; set the length, initialize iterating variable, and iterate through the array using a while loop. Here's an example.

    const arr = [];
    arr.length = 120000;
    let i = 0;
    while (i < 120000) {
      arr[i] = 0;
      i++;
    }

    Another possible implementation would be:

    (arr = []).length = n;
    let i = 0;
    while (i < n) {
        arr[i] = 0;
        i++;
    }
    

    But I strongly discourage using this second implantation in practice as it's less clear and doesn't allow you to maintain block scoping on your array variable.

    These are significantly faster than filling with a for loop, and about 90% faster than the standard method of

    const arr = Array(n).fill(0);
    

    But this fill method is still the most efficient choice for smaller arrays due to it's clarity, conciseness and maintainability. The performance difference likely won't kill you unless you're making a lot of arrays with lengths on the order of thousands or more.

    A few other important notes. Most style guides recommend you no longer use varwithout a very special reason when using ES6 or later. Use const for variables that won't be redefined and let for variables that will. The MDN and Airbnb's Style Guide are great places to go for more information on best practices. The questions wasn't about syntax, but it's important that people new to JS know about these new standards when searching through these reams of old and new answers.

    0 讨论(0)
提交回复
热议问题