Fastest JavaScript summation

前端 未结 10 2023
再見小時候
再見小時候 2020-11-27 15:13

What is the fastest way to sum up an array in JavaScript? A quick search turns over a few different methods, but I would like a native solution if possible. This will run un

相关标签:
10条回答
  • 2020-11-27 15:15

    For your specific case, just use the reduce method of Arrays:

    var sumArray = function() {
        // Use one adding function rather than create a new one each
        // time sumArray is called
        function add(a, b) {
            return a + b;
        }
    
        return function(arr) {
            return arr.reduce(add);
        };
    }();
    
    alert( sumArray([2, 3, 4]) );
    
    0 讨论(0)
  • 2020-11-27 15:21

    Or you could do it the evil way.

    var a = [1,2,3,4,5,6,7,8,9];
    
    sum = eval(a.join("+"));
    

    ;)

    0 讨论(0)
  • 2020-11-27 15:26

    I tried using performance.now() to analyze the performance of the different types of loops. I took a very large array and found the sum of all elements of the array. I ran the code three times every time and found forEach and reduce to be a clear winner.

    // For loop

    let arr = [...Array(100000).keys()]
    function addUsingForLoop(ar){
      let sum = 0;
      for(let i = 0; i < ar.length; i++){
        sum += ar[i];
      }
       console.log(`Sum: ${sum}`);
       return sum;
    }
    let t1 = performance.now();
    addUsingForLoop(arr);
    let t2 = performance.now();
    console.log(`Time Taken ~ ${(t2 - t1)} milliseconds`)
    
    // "Sum: 4999950000"
    // "Time Taken ~ 42.17500000959262 milliseconds"
    // "Sum: 4999950000"
    // "Time Taken ~ 44.41999999107793 milliseconds"
    // "Sum: 4999950000"
    // "Time Taken ~ 49.845000030472875 milliseconds"
    

    // While loop

    let arr = [...Array(100000).keys()]
    function addUsingWhileLoop(ar){
    let sum = 0;
    let index = 0;
    while (index < ar.length) {
      sum += ar[index];
      index++;
    }
      console.log(`Sum: ${sum}`)
      return sum;
    }
    let t1 = performance.now();
    addUsingWhileLoop(arr);
    let t2 = performance.now();
    console.log(`Time Taken ~ ${(t2 - t1)} milliseconds`)
    
    // "Sum: 4999950000"
    // "Time Taken ~ 44.2499999771826 milliseconds"
    // "Sum: 4999950000"
    // "Time Taken ~ 44.01999997207895 milliseconds"
    // "Sum: 4999950000"
    // "Time Taken ~ 41.71000001952052 milliseconds"
    

    // do-while

    let arr = [...Array(100000).keys()]
    function addUsingDoWhileLoop(ar){
    let sum = 0;
    let index = 0;
    do {
       sum += index;
       index++;
    } while (index < ar.length);
       console.log(`Sum: ${sum}`);
       return sum;
    }
    let t1 = performance.now();
    addUsingDoWhileLoop(arr);
    let t2 = performance.now();
    console.log(`Time Taken ~ ${(t2 - t1)} milliseconds`)
    
    // "Sum: 4999950000"
    // "Time Taken ~ 43.79500000504777 milliseconds"
    // "Sum: 4999950000"
    // "Time Taken ~ 43.47500001313165 milliseconds"
    // "Sum: 4999950000"
    // "Time Taken ~ 47.535000019706786 milliseconds"
    

    // Reverse loop

    let arr = [...Array(100000).keys()]
    function addUsingReverseLoop(ar){
       var sum=0;
       for (var i=ar.length; i--;) {
         sum+=arr[i];
       }
       console.log(`Sum: ${sum}`);
       return sum;
    }
    let t1 = performance.now();
    addUsingReverseLoop(arr);
    let t2 = performance.now();
    console.log(`Time Taken ~ ${(t2 - t1)} milliseconds`)
    
    // "Sum: 4999950000"
    // "Time Taken ~ 46.199999982491136 milliseconds"
    // "Sum: 4999950000"
    // "Time Taken ~ 44.96500000823289 milliseconds"
    // "Sum: 4999950000"
    // "Time Taken ~ 43.880000011995435 milliseconds"
    

    // Reverse while loop

    let arr = [...Array(100000).keys()]
    function addUsingReverseWhileLoop(ar){
        var sum = 0;
        var i = ar.length; 
        while (i--) {
            sum += ar[i];
        }
        console.log(`Sum: ${sum}`);
        return sum;
    }
    var t1 = performance.now();
    addUsingReverseWhileLoop(arr);
    var t2 = performance.now();
    console.log(`Time Taken ~ ${(t2 - t1)} milliseconds`)
    
    // "Sum: 4999950000"
    // "Time Taken ~ 46.26999999163672 milliseconds"
    // "Sum: 4999950000"
    // "Time Taken ~ 42.97000000951812 milliseconds"
    // "Sum: 4999950000"
    // "Time Taken ~ 44.31500000646338 milliseconds"
    

    // reduce

    let arr = [...Array(100000).keys()]
    let t1 = performance.now();
    sum = arr.reduce((pv, cv) => pv + cv, 0);
    console.log(`Sum: ${sum}`)
    let t2 = performance.now();
    console.log(`Time Taken ~ ${(t2 - t1)} milliseconds`)
    
    // "Sum: 4999950000"
    // "Time Taken ~ 4.654999997001141 milliseconds"
    // "Sum: 4999950000"
    // "Time Taken ~ 5.040000018198043 milliseconds"
    // "Sum: 4999950000"
    // "Time Taken ~ 4.835000028833747 milliseconds"
    

    // forEach

    let arr = [...Array(100000).keys()]
    function addUsingForEach(ar){
      let sum = 0;
      ar.forEach(item => {
        sum += item;
      })
        console.log(`Sum: ${sum}`);
        return sum
    }
    let t1 = performance.now();
    addUsingForEach(arr)
    let t2 = performance.now();
    console.log(`Time Taken ~ ${(t2 - t1)} milliseconds`)
    
    // "Sum: 4999950000"
    // "Time Taken ~ 5.315000016707927 milliseconds"
    // "Sum: 4999950000"
    // "Time Taken ~ 5.869999993592501 mienter code herelliseconds"
    // "Sum: 4999950000"
    // "Time Taken ~ 5.405000003520399 milliseconds"
    
    0 讨论(0)
  • 2020-11-27 15:33

    While searching for the best method to sum an array, I wrote a performance test.

    In Chrome, "reduce" seems to be vastly superior

    I hope this helps

    // Performance test, sum of an array
      var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
      var result = 0;
    // Eval
      console.time("eval");
      for(var i = 0; i < 10000; i++) eval("result = (" + array.join("+") + ")");
      console.timeEnd("eval");
    // Loop
      console.time("loop");
      for(var i = 0; i < 10000; i++){
        result = 0;
        for(var j = 0; j < array.length; j++){
          result += parseInt(array[j]);
        }
      }
      console.timeEnd("loop");
    // Reduce
      console.time("reduce");
      for(var i = 0; i < 10000; i++) result = array.reduce(function(pv, cv) { return pv + parseInt(cv); }, 0);
      console.timeEnd("reduce");
    // While
      console.time("while");
      for(var i = 0; i < 10000; i++){
        j = array.length;
        result = 0;
        while(j--) result += array[i];
      }
      console.timeEnd("while");
    

    eval: 5233.000ms

    loop: 255.000ms

    reduce: 70.000ms

    while: 214.000ms

    0 讨论(0)
  • 2020-11-27 15:34

    What about summing both extremities? It would cut time in half. Like so:

    1, 2, 3, 4, 5, 6, 7, 8; sum = 0

    2, 3, 4, 5, 6, 7; sum = 10

    3, 4, 5, 6; sum = 19

    4, 5; sum = 28

    sum = 37

    One algorithm could be:

    function sum_array(arr){
        let sum = 0,
            length = arr.length,
            half = Math.floor(length/2)
    
        for (i = 0; i < half; i++) {
            sum += arr[i] + arr[length - 1 - i]
        }
        if (length%2){
            sum += arr[half]
        }
        return sum
    }
    

    It performs faster when I test it on the browser with performance.now(). I think this is a better way. What do you guys think?

    0 讨论(0)
  • 2020-11-27 15:35

    Improvements


    Your looping structure could be made faster:


       var count = 0;
       for(var i=0, n=array.length; i < n; i++) 
       { 
          count += array[i]; 
       }
    

    This retrieves array.length once, rather than with each iteration. The optimization is made by caching the value.


    If you really want to speed it up:


       var count=0;
       for (var i=array.length; i--;) {
         count+=array[i];
       }
    

    This is equivalent to a while reverse loop. It caches the value and is compared to 0, thus faster iteration.

    For a more complete comparison list, see my JSFiddle.
    Note: array.reduce is horrible there, but in Firebug Console it is fastest.


    Compare Structures

    I started a JSPerf for array summations. It was quickly constructed and not guaranteed to be complete or accurate, but that's what edit is for :)

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