2008-11-03 12 views
15

Bir Expression<T> derlendiğinde, sonuç kodu kod tarafından gizlice önbelleğe alınır mı? Çerçevenin, son birkaç ifadeyi dolaylı olarak derlediği ve önlediği statik Regex yöntemlerinin çizgileri boyunca düşünüyorum. derlenmiş Expression<T> nesneler değil önbelleğe değilsenizBir İfade <T> derlendiğinde, örtülü olarak önbelleğe alınmış mı?

, aşağıya derleme zamanı tutmak için bazı en iyi uygulamaları veya el bir ifade önbelleğe sorunlara neden olabilecek herhangi bir FRİKİKLERİNDEN tavsiye edebilir?

Bu örnekte
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; 
} 

, ben olsam bu değerleri almak yerine, ben derlenmiş ifadeyi önbelleğe eğer anda ifade derlendi gibi, bu arg1 ve arg2 değerlerini kullanacaktır o biraz endişeliyim Yığındaki uygun yerlerden (yani mevcut değerleri almak yerine).

cevap

10

Hayır; Bunun olduğuna inanmıyorum; Önbelleğe almak istiyorsanız, Delegate başvurusuna (genellikle Func<...> veya Action<...>) tutun. Aynı şekilde, en iyi performansı elde etmek istiyorsanız, onu parametreli bir ifade olarak derlersiniz, böylece bunu çağırdığınızda farklı değerler gönderebilirsiniz.

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; 
} 

yani ekspresyon numaraları parametreler için, ve (daha çok ifade olmak sabitler yerine) zamanında gerçek olanları geçmek:

Bu durumda, yeniden cümleleme yardımcı olacaktır.

+1

Merhaba Mark, Bu tür optimizasyonlarla hiç karşılaşmadım. Bu işlemin, önceden derlenmiş sorguların önbelleğe alınması, perfomance açısından gerçekten yararlı olup olmadığını bildirir misiniz? –

1

Lambda genişletme işlemleri otomatik olarak önbelleğe alınmaz. Bunun için kendi önbelleğe alma/not alma algoritmalarını uygulamanız gerekecektir. ilgili Stackoverflow soru edin:

Is it possible to cache a value evaluated in a lambda expression?

O lambda ifadeleri C# değerlendirilen tembel dikkat etmek önemlidir.

İlgili konular