2013-11-20 2 views
17

현재 소스 코드를 HTML 형식의 텍스트로 강조 표시하는 프로그램을 만들고 있습니다. 내가 그것을 테스트했을 때, 나는 이상한 결과를 발견했다. Chrome에서는 프로그램이 거의 즉각적으로 1000 줄의 소스를 파싱합니다. 그러나 파이어 폭스는 동일한 1000 라인을 분석하는데 30 초가 걸린다. 아이러니하게도 IE10은 18 초 밖에 걸리지 않습니다.Chrome이 즉시 수행하는 작업, Firefox가 30 초 걸리는 시간

다른 브라우저에서 자바 스크립트를 다르게 구현하고 Chrome의 속도가 빨라지 긴하지만 30 일 이상 Firefox를 사용하는 이유를 알 수 없습니다. 각각 10000000000 개의 원시 while 루프 테스트를 실행했으며 FF 14 초 및 Chrome 12를 사용했습니다. 따라서 코드 내 어딘가에서 Firefox가 비정상적으로 오랜 시간이 걸릴 것으로 생각됩니다. 나는 연구를 해왔지만, 지금까지 발견하지 못했던 것은 내가보기에 커다란 불일치를 나타낼 것입니다.

그럼,이 문제를 일으키는 원인이 무엇인지에 대한 의견이있는 사람이 있습니까? 아래 코드의 문제 영역을 게시했습니다 (이 부분을 주석 처리하면 두 브라우저가 모두 즉시 구문 분석합니다). startend은 모두 정규 표현식입니다. istream은 소스 코드가 들어오는 곳이고, ostream은 파싱 된 코드가있는 곳입니다. istream.read()은 String slice() 메서드를 호출합니다. 마지막으로이 함수는 프로그램 전체에서 여러 번 호출됩니다.

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()) && (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("@<&#160;&#160;&#160;&#160;>@"); 
       continue; 
      } 
      else if(istream.peek() == " "){ 
       istream.read(); 
       ostream.write("@<&#160;>@"); 
       continue; 
      } 
      ostream.write(istream.read()); 
     } while(!istream.isEmpty() && !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; 
} 

어떤 통찰력

크게 감상 할 수있다, 당신이 특정 측면이 어떻게 구현되는지에 관한 의문 사항이있는 경우, 내가 은혜를 베풀 것입니다. 미리 감사드립니다. IStream을하고 ostream에 객체의

정의 :

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; } 
} 
+1

당신이 입술의 모양을 우리에게 보여줄 수 ('start'와'end') : 여기

엄격한 VS 느슨한의 jsperf입니까? – Flimzy

+0

ostream.write는 어디에 있습니까? 문자열이나 DOM에 직접 연결 하시겠습니까? – user2864740

+1

아마도 원인은 아니지만, 한 가지 빠른 변화는'istream.peek()'호출을'do' 문 앞에 한 번 호출로 옮기는 것입니다. – Graham

답변

1

나는 모든 .read() 전화에 당신이 content.slice(1)을 때문입니다 생각하고 모든 시간을 복사 전체 문자열하지만 첫 번째 문자와 시간이 많이 걸릴 수 있습니다. 이처럼 IOStream 클래스를 modifyin보십시오 :

function IOstream(init){ 
    this.content = init; 
    this.cursor = 0; 

    this.read = function(){ 
     var tmp = this.content.charAt(this.cursor); 
     this.cursor++; 
     return tmp; 
    }; 
    this.peek = function(){ return this.content.charAt(this.cursor); }; 
    this.write = function(str){ this.content += str; }; 
    this.isEmpty = function(){ return this.cursor>=this.content.length; } 
} 

나는 그것이 모든 브라우저에서 당신의 속도 문제를 해결 것이라 생각합니다.

관련 문제