Improve performance when ordering array

0

I have created a function on my own to order arrays in a descendant way and I would like to modify it to have a close performance compared to the native function of Javascript, here it is:

function essorted(...arr) {
  var o = [],
    max = arr.length,
    f = 0;
  for (; f < max; f++) {
    var flag = 0,
      a = arr[f];
    while (a > o[o.length - 1 - flag] && flag > -1) {
      flag += 1;
    }
    /* Si el elemento actual es mayor que el elemento el cual se está recorriendo en el array ordenado "o", este sumará +1 a flag para así seguir buscando y parará cuando sea menor o flag sea = 0 , con esto
puedo encontrar la ubicación de donde debe ir el número, según:

o.length - flag 

*/

    o.splice(o.length - flag, 0, a);
  }
  return o;
}
var a = [4, 9, 3, 0, 77, 1, 108, 5, 6, 2, 1000];
console.log(essorted.apply(null, a));

Additionally I would like to know:

  • Why low performance?
  • What are the errors or antipatterns of my code?
asked by Eduardo Sebastian 03.11.2017 в 02:46
source

1 answer

0

It does not try to be an answer, but by doing some tests to order numbers in descending order, between your code and the native function .sort() , it is evident what you indicate.

In these demonstrations I am using setTimeout() to execute the comparisons to avoid the accumulation of effort of the browser when executing code simultaneously, and thus have more accurate measurements.

Comparison between developed function and native function sort() :

function essorted(...arr) {
  var o = [],
    max = arr.length,
    f = 0;
  for (; f < max; f++) {
    var flag = 0,
      a = arr[f];
    while (a > o[o.length - 1 - flag] && flag > -1) {
      flag += 1;
    }
    /* Si el elemento actual es mayor que el elemento el cual se está recorriendo en el array ordenado "o", este sumará +1 a flag para así seguir buscando y parará cuando sea menor o flag sea = 0 , con esto
puedo encontrar la ubicación de donde debe ir el número, según:

o.length - flag 

*/

    o.splice(o.length - flag, 0, a);
  }
  return o;
}
setTimeout(function() {
  console.time("Custom sort");
  var a = [4, 9, 3, 0, 77, 1, 108, 5, 6, 2, 1000];
  console.log(essorted.apply(null, a));
  console.timeEnd("Custom sort");


  setTimeout(function() {
    console.time("Native sort");
    var b = [4, 9, 3, 0, 77, 1, 108, 5, 6, 2, 1000];
    console.log(b.sort(function(a, b) {
      return b - a;
    }));
    console.timeEnd("Native sort");
  }, 2000);
}, 1000);

Google Chrome: Version 61.0.3163.100 (Official build) (64 bits)

What I find in your code is that you are:

  • Creating and initializing variable flag within a loop. Better to create the variable outside the loop and just initialize it in the loop.
  • You are calculating the number of elements in an array in a loop. Better to create a variable len outside the loop and update its value in the loop.
  • flag > -1 will always meet that condition. We better retire it.
  • Final comparison between developed version and enhanced version:

    function essorted(...arr) {
      var o = [],
        max = arr.length,
        f = 0;
      for (; f < max; f++) {
        var flag = 0,
          a = arr[f];
        while (a > o[o.length - 1 - flag] && flag > -1) {
          flag += 1;
        }
        /* Si el elemento actual es mayor que el elemento el cual se está recorriendo en el array ordenado "o", este sumará +1 a flag para así seguir buscando y parará cuando sea menor o flag sea = 0 , con esto
    puedo encontrar la ubicación de donde debe ir el número, según:
    
    o.length - flag 
    
    */
    
        o.splice(o.length - flag, 0, a);
      }
      return o;
    }
    
    function essorted2(...arr) {
      var o = [],
        max = arr.length,
        f = 0,
        flag, len; // Se crean las variables sin valor inicial, fuera del bucle.
      for (; f < max; f++) {
        flag = 0, // Se asigna el valor de la variable flag.
          a = arr[f],
          len = o.length; // Se actualiza el valor de la variable len dentro del bucle for pero fuera del while.
        while (a > o[len - 1 - flag]) { // Se utiliza los valores de las variables len y flag. Esta parte podría mejorarse.
          flag += 1;
        }
        /* Si el elemento actual es mayor que el elemento el cual se está recorriendo en el array ordenado "o", este sumará +1 a flag para así seguir buscando y parará cuando sea menor o flag sea = 0 , con esto
    puedo encontrar la ubicación de donde debe ir el número, según:
    
    o.length - flag 
    
    */
        o.splice(len - flag, 0, a);
      }
      return o;
    }
    
    
    setTimeout(function() {
      console.time("essorted");
      var a = [4, 9, 3, 0, 77, 1, 108, 5, 6, 2, 1000];
      console.log(essorted.apply(null, a));
      console.timeEnd("essorted");
    
      setTimeout(function() {
        console.time("essorted2");
        var b = [4, 9, 3, 0, 77, 1, 108, 5, 6, 2, 1000];
        console.log(essorted2.apply(null, b));
        console.timeEnd("essorted2");
      }, 2000);
    }, 1000);

    With this you can have a slight improvement.

    Google Chrome: Version 61.0.3163.100 (Official build) (64 bits)

    I recommend you check link , which mentions the implementation of Array.sort() . You could have additional information about the implementation algorithm of this function.

    As indicated by @ frikinside, I recommend you refer this question to link .

        
    answered by 04.11.2017 в 18:09