Когда Выражение <T> компилируется, разве оно неявно кэшируется?

Когда 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 когда они были в то время, когда выражение было скомпилировано, вместо того, чтобы получить те значения от соответствующего места в стеке (т.е. вместо того, чтобы получить текущие значения).

16
задан Damian Powell 3 November 2008 в 14:50
поделиться

2 ответа

Нет; я не полагаю, что это; если Вы хотите кэшируемый, необходимо держать на 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;
}

т.е. делают параметры чисел выражения и передают фактический это во времени выполнения (вместо того, чтобы быть константами в выражении).

11
ответ дан 30 November 2019 в 23:00
поделиться

Выражения лямбды не кэшируются автоматически. Необходимо будет реализовать Вас, владеют caching/memoization алгоритмами для этого. Проверьте связанный вопрос о Stackoverflow:

это возможный кэшировать значение, оцененное в лямбда-выражении?

важно отметить, что лямбда-выражения ленивы оцененный в C#.

2
ответ дан 30 November 2019 в 23:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: