2009-09-22 2 views
3

몇 가지 정보를 람다 식으로 전달하여 일부 메서드에 전달해야합니다. 기본적으로 데이터베이스 쿼리에 정보를 추가하는 방법입니다. 간단한 예는 다음과 같습니다 그것은 내가 큰 perfomance에 영향을 미치는 매개 변수 개체를 얻을 수 LambdaExpression.Compile를 호출 할 필요가 있다는 사실을 제외하고 꽤 잘 작동하고컴파일 된 람다 식 캐싱

companyData.GetAll(
    where => "SomeField = @SOMEFIELD", 
    order => "Id", 
    SOMEFIELD => new Parameter {DbType = DbType.String, Value = "some value"} 
) 

. 이제 오는 약 700

에 10000 반복에 약 35000 밀리 초에서 :이 클래스는 큰 차이를 만들어

class ExpressionCache<T,U> 
{ 

    private static ExpressionCache<T, U> instance; 
    public static ExpressionCache<T, U> Instance 
    { 
     get 
     { 
      if (instance == null) { 
       instance = new ExpressionCache<T, U>(); 
      } 
      return instance; 
     } 
    } 

    private ExpressionCache() { } 

    private Dictionary<string, Func<T, U>> cache = new Dictionary<string, Func<T, U>>(); 

    public Func<T, U> Get(Expression<Func<T, U>> expression) 
    { 
     string key = expression.Body.ToString(); 
     Func<T,U> func; 
     if (cache.TryGetValue(key, out func)) { 
      return func; 
     } 
     func = expression.Compile(); 
     cache.Add(key, func); 
     return func; 
    } 
} 

: 더 빠른 결과를 얻을 수

, 나는이 순진 캐싱 테스트와 함께 왔어요 질문 : 표현의 본문을 사전의 핵심으로 사용하기 위해 어떤 종류의 문제가 발생할 것인가?

답변

9

표현 트리를 델리게이트로 컴파일하는 것이 왜 필요한지는 분명하지 않습니다. 왜 그냥 대리자를 사용하여 람다 식을 표현식 트리가 아닌 대리자로 변환하는 컴파일러를 얻지 않습니까?

문자열의 본문을 사용하는 경우 - 서로 다른 유형이지만 동일한 속성 이름을 사용하는 이상한 경우가 발생할 수 있습니다. 그러나 유형을 제네릭 형식 매개 변수로 이미 사용하고 있다는 것을 감안할 때 문제는 아닐 것입니다 ... 을 맹세하고 싶습니다.

아, 그리고 귀하의 싱글 톤 캐시가 도중에 스레드로부터 안전하지 않습니다. 고정 이니셜 라이저에서 instance 변수를 초기화하는 것이 좋습니다. 이것은 더 간단한 코드로 이어지고 더 안전합니다 ...

private static readonly ExpressionCache<T, U> instance 
    = new ExpressionCache<T, U>(); 
public static ExpressionCache<T, U> Instance { get { return instance; } } 
+2

+1 "아, 그리고 당신의 싱글 톤 캐시가 스레드 안전하지 않습니다." –

+0

@ Dan : 조금 더 많은 도움이 필요하다고 생각합니다. –

+0

@ 존 : 스레드로부터 안전하지 않다는 것을 알았습니다. 그것은 단지 시험이었습니다. "Just delegates"아이디어에 감사드립니다. 나는이 람다 일에 너무 멍청하다고 생각한다. – Fernando

9

람다 식으로 클로저를 만들 수 있습니다. 이 경우 표현식 본문에 결과 코드로 들어가는 모든 내용이 포함되지 않습니다. 포함될 잠재적으로 중요한 로컬 변수가 누락 될 수 있습니다.

+2

아직까지도 캐싱을 유지하기위한 해결책은 없습니까? – TobiHeidi