Increasing performance of loops
<p>I'm currently working on a script that helps to manage connections to phone numbers with different things like contacts, text messages, etc. The big problem with phone numbers in our data is that a phone number can be something like..</p>

<pre><code>13334445555
3334445555
013334445555
444555
</code></pre>

<p>All of these would probably be the same number. So, I've got a 'lookupNumber' method on an object that contains all sorts of references (none of which are important for this question), and a hasVariant method on each 'cloud' - a name that I gave to an object that represents one or more variations of a phone number. The 'cloud' could start off with a shorter number than the ones given to it, so it has to be able to vary which number it is trying to place.</p>

<p>The object with all the 'clouds' has a relevant data structure of:</p>

<pre><code>{
  clouds: [], //0-n clouds
  phoneNumberCache: {} //i.e. 333444555: {//ref to cloud}
}
</code></pre>

<p>The 'clouds' have the relevant data structure of:</p>

<pre><code>{
  numbers: [] //1-n numbers
}
</code></pre>

<p>lookupNumber method:</p>

<pre><code>lookupNumber: function (number) {
  if(this.phoneNumberCache[number] === undefined) {
    var i, l, cloud;
    for (i = 0, l = this.clouds.length; i &lt; l; i++) {
      cloud = this.clouds[i];
      if(cloud.hasVariant(number)) {
        this.phoneNumberCache[number] = cloud;
        return cloud;
      }
    }
    return false;
  } else {
    return this.phoneNumberCache[number];
  }
}
</code></pre>

<p>hasVariant method:</p>

<pre><code>hasVariant: function (testNumber) {
  for(var i = 0, l = this.numbers.length; i &lt; l; i++) {
    var number = this.numbers[i], needle, haystack, index, needleLength, haystackLength;

    if(testNumber.length &lt; number.length) {
      needle = testNumber;
      haystack = number;
    } else {
      needle = number;
      haystack = testNumber;
    }
    needleLength = needle.length;
    haystackLength = haystack.length;

    if(needleLength &lt;= this.minimumLength &amp;&amp; haystackLength != needleLength) {
      continue;
    }

    index = haystack.indexOf(needle);

    if(index != -1 &amp;&amp; (index + needleLength) == haystackLength &amp;&amp; (needleLength / haystackLength) &gt; this.minimumMatch) {
      return true;
    }

  }
  return false;
}
</code></pre>

<p>On my testing account, the performance is 'meh' on firefox and terrible on IE8 (the minimum IE browser we support). Firebug is reporting the following times for the two methods:</p>

<pre><code>Function        Calls   Percent Own Time    Time        Avg     Min     Max
hasVariant      1355484 32.1%   1653.577ms  1653.577ms  0.001ms 0.001ms 0.205ms 
lookupNumber    2120    31.17%  1605.947ms  3259.524ms  1.538ms 0.001ms 4.736ms
</code></pre>

<p>The test data has 1674 unique phone numbers in it - about 450 of the 'lookupNumber' calls are going to return an already cached number. </p>

<p>Maybe I've been staring at the data too long, but it seems the number of times the 'hasVariant' gets called is way too high and they're both such simple methods.. I can't think of any way to make them faster. Because it's still very slow on IE, I'm still looking for a way to squeeze some more performance out of it. Any ideas on how to make this more efficient? Or do I have a bug in here that might be causing this to not cache a number?</p>
