Search code examples
javascriptperformancegoogle-apps-scriptgoogle-sheetscustom-function

Slow Performance Custom Script GAS


So, I've written (for lack of answers + improving my skills) a search script that would do basically what .indexOf does.

function search(ref, data) {

  var x
  var y
  var result = []

  if (data == '' || data == null) {
  } else {
    for (x = 0; x < data.length; x++) {
      if (data[x] == ref[0]) {                //achando match inicial
        var proto = [];
        for (y = 0; y < ref.length; y++) {
          if (data[x+y] == ref[y]) {          //gravando tentativas de match completo
          proto.push(data[x+y])
          }
        }
        var proto2 = proto.join('')
        if (proto2 == ref) {                   //testando match completo
            result.push(x)
        }
      }
    }
  }
  if (result == '' || result == null) {
  } else {
    return result[0]
  }
}

It works fine within other little codes and custom functions that do not require too much looping, but when I wrote a more robust script I found that my code is roughly 3000x slower than the native .indeOf.

Why would I incur in such a difference?


Solution

  • Issue:

    Your function is comparing each character from ref separately with a data character, in an inner loop, pushing each character match inside an array (proto) and using join to transform the array back to a string (proto2), before comparing it to the original ref.

    This is extremely inefficient and could be greatly simplified, so no question this function is much slower than String.prototype.indexOf().

    Solution:

    You could have a single loop instead, iterating through data, and for each iteration, retrieve a slice of data with the same length as ref, before comparing this slice with ref. If both values match, the string ref has been found in data, and the corresponding index is returned:

    function searchString(ref, data) {
      for (let i = 0; i <= data.length - ref.length; i++) {
        if (ref === data.slice(i, i + ref.length)) return i;
      }
      return -1;
    }
    

    While using this function, I get similar execution times than with indexOf.

    Reference: