문제

언제 Expression<T> 컴파일 된 결과, 결과 코드는 프레임 워크에 의해 암시 적으로 캐시됩니까? 나는 정적의 선을 따라 생각하고있다 Regex 프레임 워크가 마지막 몇 개의 regexes를 암시 적으로 컴파일하고 캐시하는 방법.

컴파일 된 경우 Expression<T> 물체는 ~ 아니다 캐시드, 컴파일 타임을 낮추기위한 몇 가지 모범 사례를 추천 할 수 있습니까?

public MyResultType DoSomething(int arg1, int arg2)
{
    var result = invokeHandler(
        (IDoSomethingHandler h) => h.DoSomething(arg1, arg2)
    );
    return result;
}

private TResult invokeHandler<T, TResult>(Expression<Func<T, TResult>> action)
    where T : class
{
    // Here, I might want to check to see if action is already cached.

    var compiledAction = action.Compile();
    var methodCallExpr = action as MethodCallExpression;

    // Here, I might want to store methodCallExpr in a cache somewhere.

    var handler = ServiceLocator.Current.GetInstance<T>();
    var result = compiledAction(handler);

    return result;
}

이 예에서는 컴파일 된 표현식을 캐시하면 값을 사용하는 것이 약간 우려됩니다. arg1 그리고 arg2 그들이 당시에 있었던 것처럼, 표현식은 스택의 적절한 위치에서 해당 값을 검색하기보다는 (즉, 현재 값을 얻지 않고).

도움이 되었습니까?

해결책

아니; 나는 그것이 믿지 않는다. 캐시를 원한다면 Delegate 참조 (일반적으로 Func<...> 또는 Action<...>). 마찬가지로, 최상의 성능을 얻으려면 매개 변수화 된 표현식으로 컴파일하므로 호출 할 때 다른 값을 보낼 수 있습니다.

이 경우 리페이스가 도움이됩니다.

public MyResultType DoSomething(int arg1, int arg2)
{
    var result = invokeHandler(
        (IDoSomethingHandler h, int a1, int a2) => h.DoSomething(a1, a2),
        arg1, arg2);
    return result;
}

private TResult invokeHandler<T, TResult>(Expression<Func<T,int,int,TResult>> action,
    int arg1, int arg2)
    where T : class
{
    // Here, I might want to check to see if action is already cached.

    var compiledAction = action.Compile();
    var methodCallExpr = action as MethodCallExpression;

    // Here, I might want to store methodCallExpr in a cache somewhere.

    var handler = ServiceLocator.Current.GetInstance<T>();
    var result = compiledAction(handler, arg1, arg2);

    return result;
}

즉, 표현식의 숫자 매개 변수를 만들고 실제 런타임에 (표현에서 상수가 아닌).

다른 팁

람다 지출은 자동으로 캐시되지 않습니다. 이를 위해 자신의 캐싱/메모 화 알고리즘을 구현해야합니다. 관련 stackoverflow 질문을 확인하십시오.

람다 표현식으로 평가 된 값을 캐시 할 수 있습니까?

Lambda 표현은 C#에서 게으른 평가를 받았다는 점에 유의해야합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top