2013-03-14 6 views
1

웹 응용 프로그램의 사용자 정의 템플리트 시스템의 일부로 많이 사용되는 C# 정규 표현식으로 작업했습니다. 표현식은 복잡하며 Regex.Compiled 옵션을 사용하면 실제 성능이 향상됩니다. 그러나 컴파일의 초기 비용은 개발 과정에서, 특히 반복 단위 테스트에서 자극적입니다 (이 일반적인 상쇄 관계는 here으로 언급 됨).별도의 스레드에서 .NET 정규 표현식을 게으르게 컴파일

현재 제가 시도하는 한 가지 해결책은 게으른 정규식 컴파일입니다. 아이디어는 별도의 스레드에서 Regex의 컴파일 된 버전을 작성하고 준비가되었을 때 하위 영역에 넣음으로써 두 가지 장점을 모두 얻을 수 있다는 것입니다.

내 질문은 : 이것이 성능이 좋지 않거나 그렇지 않은 이유가 무엇입니까? jitting이나 어셈블리 로딩 같은 것들을 스레드로 분산시키는 것이 정말로 효과가 있는지는 잘 모르겠다. (비록 내 벤치 마크에서 나온 것처럼 보이지만). 당신이 컴파일 시간 단계로 Regex.CompileToAssembly를 사용하려면 같은

public class LazyCompiledRegex 
{ 
    private volatile Regex _regex; 

    public LazyCompiledRegex(string pattern, RegexOptions options) 
    { 
     if (options.HasFlag(RegexOptions.Compiled)) { throw new ArgumentException("Compiled should not be specified!"); } 
     this._regex = new Regex(pattern, options); 
     ThreadPool.QueueUserWorkItem(_ => 
     { 
      var compiled = new Regex(pattern, options | RegexOptions.Compiled); 
      // obviously, the count will never be null. However the point here is just to force an evaluation 
      // of the compiled regex so that the cost of loading and jitting the assembly is incurred here rather 
      // than on the thread doing real work 
      if (Equals(null, compiled.Matches("some random string").Count)) { throw new Exception("Should never get here"); } 

      Interlocked.Exchange(ref this._regex, compiled); 
     }); 
    } 

    public Regex Value { get { return this._regex; } } 
} 
+1

왜'Lazy '을 사용하지 않을까요? – leppie

+0

기존의 Regex 캐시를 어떻게 든 활용할 수 있습니까? http://msdn.microsoft.com/en-us/library/system.text.regularexpressions.regex.cachesize.aspx – spender

+0

정직하게 말하면, 이것은 [codereview] (http://codereview.stackexchange.com/)에 더 적합 할 수 있습니다.) – hometoast

답변

6

그것은 소리 : 여기에 코드입니다.

+0

정확합니다. 나를 때려. –

+0

정규식에서 쉽게 반복하면서 (예 : 템플릿 언어에 기능을 추가하는 등) 여전히 빌드 프로세스에이를 추가하는 쉬운 방법이 있습니까? – ChaseMedallion

+1

@ChaseMedallion : 명령 줄 앱을 작성하고 사전/사후 빌드 단계의 일부로 호출 할 수 있습니다. – leppie

관련 문제