2011-03-10 2 views
4

일부 ddump 파일을 구문 분석하려고하는데 알고리즘 속도를 높이는 데 도움이 될 수 있습니까?
각 루프마다 216ms가 걸립니다 !! 그건 너무 비싸다. 루프 당 약 40 ~ 50 밀리 초 정도가 필요합니다. 어쩌면 RegExp를 사용했을까요? 어떤 도움을 크게 감상 할 수구문 분석 알고리즘 속도 향상

 while (pos < EntireFile.Length && (/*curr = */EntireFile.Substring(pos, EntireFile.Length - pos)).Contains(" class")) 
      { 
       w.Reset(); 
       w.Start(); 
       pos = EntireFile.ToLower().IndexOf(" class", pos) + 6; 
       int end11 = EntireFile.ToLower().IndexOf("extends", pos); 
       if (end11 == -1) 
        end11 = EntireFile.IndexOf("\r\n", pos); 
       else 
       { 
        int end22 = EntireFile.IndexOf("\r\n", pos); 
        if (end22 < end11) 
         end11 = end22; 
       } 
       //string opcods = EntireFile.Substring(pos, EntireFile.Length - pos); 
       string Cname = EntireFile.Substring(pos, end11 - pos).Trim(); 
       pos += (end11 - pos) + 7; 
       pos = EntireFile.IndexOf("{", pos) +1;

int count = 1; string searching = EntireFile.Substring(pos, EntireFile.Length - pos); int searched = 0; while (count != 0) { if (searching[searched] == '{') count++; else if (searching[searched] == '}') count--; searched++; } string Content = EntireFile.Substring(pos, searched); tlist.Add(new TClass() { ClassName = Cname, Content = Content }); pos += searched; if (pos % 3 == 0) { double prc = ((double)pos) * 100d/((double)EntireFile.Length); int prcc = (int)Math.Round(prc); wnd.UpdateStatus(prcc); wnd.Update(); } mils.Add((int)w.ElapsedMilliseconds); }

:

여기 내 algrithm입니다.

+2

덤프의 형식을 알고하는 동안의 끝에서 수행 할 파일이 있습니다. 파일 크기는 얼마입니까? 공유 할 수있는 데이터의 샘플이 있습니까? –

+0

루프 외부에서 'EntireFile.ToLower() '를 이동하는 것이 합리적 일 수 있지만, 가장 많이 손상된 프로파일 러에게 요청해야합니다. 샘플 데이터와 완벽한 작업 프로그램을 입증 한 사람은 누군가와 함께 게임 할 시간을 가질 수 있습니다. –

+0

그것의 Nemo 440 덤프 파일,하지만 난 원래 그것을 디 컴파일에 관한 morallical 토론을 생산할 수 있기 때문에 그것을 게시하고 싶지 않았어 ... – alex

답변

9

음이 여러 번 확실히 도움이되지 않습니다

EntireFile.ToLower() 

을하고. 몇 가지 당신이 할 수 있습니다 :

  1. 이 (ToLower, IndexOf 등) 한 번만 비용이 많이 드는 작업을 수행하고 가능한 결과를 캐시합니다.
  2. 처리중인 입력을 SubString으로 좁히지 마십시오. 그러면 성능이 저하됩니다. 대신 int parseStart 값을 별도로 유지하고이 값을 모든 IndexOf 호출에 대한 추가 매개 변수로 사용하십시오. 즉, 매번 작은 하위 문자열을 사용하는 대신 수동으로 파싱 한 파일의 부분을 추적하십시오.
+1

이걸 추가하면 ... 그 메소드의 결과를 변수에 넣고 다시 사용하십시오. 그렇지 않으면 전체 파일을 가져 와서 전화 할 때마다 소문자로 모든 것을 처리해야합니다. –

+0

확인. 하지만 반환 할 부분 문자열이 필요합니다. – alex

+0

나는 이것에 @ 존과 함께있다. –

1

성능 문제는 모든 문자열 복사 작업으로 인한 오버 헤드와 관련되어 있습니다.

단순히 인덱스를 사용하여 차이를 만들 전체 문자열을 부분적으로 복사하여 제거하면 문자열 연산의 유효한 범위를 지정하는 오버로드가 있습니다.

또한 대소 문자를 구별하지 않는 비교는 문자열을 낮추거나 올리면 수행되지 않습니다. StringComparer 클래스 또는 StringComparsion 열거 형을 사용합니다. 대소 문자 구분을 고려할지 여부를 지정하는 많은 문자열 오버로드가 있습니다.

대괄호 표기법을 사용하여 문자열을 반복적으로 인덱싱하는 것은 매우 비쌉니다. .NET에서 문자열 연산의 구현을 살펴보면 검색 문자열을 항상 char 배열로 변환합니다. 그러나 이는 읽기 전용 검색 작업에 대해서도 여전히 많은 복사 작업이 진행되고 있음을 의미합니다.

1

코드 속도가 느려지는 부분에서 프로파일 링 도구를 사용하는 것이 좋습니다.

JetBrains dotTrace는 이러한 종류의 작업에 큰 도움이되는 프로파일 링 제품 중 하나입니다.

+0

개미 프로파일 러는 또 다른 대안으로, 둘 다 시간 제한 시험 버전입니다. –

+0

마찬가지로 slimtune입니다. http://code.google.com/p/slimtune/에서 확인하십시오. – Davido

1

Jon의 답변 외에도 코드의 while() 부분에있는 모든 내용이 각 루프에서 실행됩니다. 따라서 while 루프 반복마다

EntireFile.Substring(pos, EntireFile.Length - pos)).Contains(" class") 

을 다시 계산하지 않는 방법을 찾는 것이 더 빠를 수도 있습니다. 또한 정확히 무엇을 구문 분석하려고합니까? 일반 텍스트 파일입니까? 당신은 많은 세부 사항을주지 않았습니다. 텍스트 파일을 구문 분석하는 데 사용하는 한 가지 방법은 '\ n'을 구분 기호로 사용하여 전체 파일을 문자열 배열에로드하는 것입니다. 그런 다음 배열을 빠져 나와 내용을 파싱 할 수 있습니다.필요한 경우 배열 색인을 저장하고 이전 줄을 빠르게 참조 할 수 있습니다.

1

첫째로, 당신은 그 변경

var loweredEntireFile = EntireFile.ToLower(); 

while (pos < loweredEntireFile.Length && 
     Regex.IsMatch(loweredEntireFile, " class", 
     RegexOptions.IgnoreCase) 
{ 
... 

    // we just need to process the rest of the file 
    loweredEntireFile = loweredEntireFile.Substring(pos, loweredEntireFile.Length - pos)); 
} 

while (pos < EntireFile.Length && (/*curr = */EntireFile.Substring(pos, EntireFile.Length - pos)).Contains(" class")) 
{ 
... 
} 

을 변경할 수 있습니다

pos = EntireFile.ToLower().IndexOf(" class", pos) + 6; 
int end11 = EntireFile.ToLower().IndexOf("extends", pos); 

var matches = Regex.Matchs(loweredEntireFile, " class", RegexOptions.IgnoreCase); 
pos = matches.First().Index; 

matches = Regex.Matchs(loweredEntireFile, "extends", RegexOptions.IgnoreCase); 
var end11 = matches.First().Index; 
에 제안 기타로 14,,

var loweredEntiredFile = EntiredFile.ToLower(); 

는 동안 외부에 한 번 수행되어야하고,

loweredEntireFile = loweredEntireFile.Substring(pos, loweredEntireFile.Length - pos)); 

필요성은 내가 궁금