title: What Chrome does instantly, Firefox takes 30 seconds
body: <p>Currently, I am creating a program that will turn source code into highlighted HTML-like text.  When I tested it, though, I found some strange results.  On Chrome, the program will parse 1000 lines of source almost instantaneously.  Firefox, however, takes 30 seconds to parse the same 1000 lines.  And, ironically enough, IE10 only takes 18 seconds.</p>
  
  <p>Now, I understand that different browsers implement javascript differently and that Chrome tends to be faster, but I do not understand why it is taking Firefox over 30 times longer.  I ran a raw while-loop test of 10,000,000,000 operations on each, and it took FF 14 seconds and Chrome 12.  Therefore, I am inclined to believe that somewhere in my code is something that takes Firefox an abnormally long time to accomplish; I've done research, but nothing I've found so far would indicate the large discrepancy I am seeing.</p>
  
  <p>So, does anyone have any suggestions as to what may be causing this?  I've posted the problem area of the code below (commenting this portion out causes both browsers to parse instantaneously).  <code>start</code> and <code>end</code> are both regular expressions; <code>istream</code> is where the source code is coming from, and <code>ostream</code> is where parsed code goes to.  <code>istream.read()</code> calls the String slice() method.  Finally, this function is called many many times throughout the program.</p>
  
  <pre><code>function(buffer, istream, ostream){
      if(start.test(istream.content)){
          buffer = istream.read();
          ostream.write('[[span class="' + type + '"]]' + buffer);
          do{
              /* Special Cases */
              if(end.test(ostream.content + istream.peek()) &amp;&amp; (istream.peek() == "\n" || istream.peek() == " " || istream.peek() == "\t")){
                  include = true;
                  break;
              }
              else if(istream.peek() == "\n"){
                  istream.read();
                  ostream.write('[[/span]][[/span]]\n[[span class="line"]][[span class="' + type + '"]]');
                  continue;
              }
              else if(istream.peek() == "\t"){
                  istream.read();
                  ostream.write("@&lt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&gt;@");
                  continue;
              }
              else if(istream.peek() == " "){
                  istream.read();
                  ostream.write("@&lt;&amp;#160;&gt;@");
                  continue;
              }
              ostream.write(istream.read());
          } while(!istream.isEmpty() &amp;&amp; !end.test(ostream.content));
  
          if(include || istream.isEmpty())
              ostream.write('[[/span]]');
          else{
              var ending = ostream.content.length-1;
              while(!end.test(ostream.content.substr(ending)))
                  --ending;
              istream.content = ostream.content.substr(ending) + istream.content;
              ostream.content = ostream.content.substring(0, ending) + '[[/span]]';
          }
          return true;
      }
      return false;
  }
  </code></pre>
  
  <p>Any insight would be greatly appreciated, and if you have any queries as to how certain aspects of this are implemented, I will oblige.  Thanks in advance.</p>
  
  <p>Definition of istream and ostream objects:</p>
  
  <pre><code>function IOstream(init){
      this.content = init;
  
      this.read = function(){
          var tmp = this.content.charAt(0);
          this.content = this.content.slice(1);
          return tmp;
      };
      this.peek = function(){  return this.content.charAt(0); };
      this.write = function(str){  this.content += str; };
      this.isEmpty = function(){  return this.content.length == 0; }
  }
  </code></pre>