2008-11-03 7 views
15

जब Expression<T> संकलित किया गया है, परिणामी कोड ढांचे द्वारा पूरी तरह से कैश किया गया है? मैं स्थिर Regex विधियों की तर्ज पर सोच रहा हूं जहां ढांचा आखिरकार संकलित करता है और पिछले कुछ regexes कैश करता है।जब एक अभिव्यक्ति <T> संकलित है, तो क्या यह स्पष्ट रूप से कैश किया गया है?

तो संकलित Expression<T> वस्तुओं कैश्ड नहीं हैं, तो आप या संकलन समय नीचे रखने के लिए कुछ सर्वोत्तम प्रथाओं किसी भी gotchas कि समस्याएं पैदा कर सकता है, तो मैं मैन्युअल रूप से एक अभिव्यक्ति कैश सिफारिश कर सकते हैं?

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 के मूल्यों का उपयोग करेगा के रूप में वे समय में कर रहे थे अभिव्यक्ति संकलित किया गया है, बल्कि उन मूल्यों को पुन: प्राप्त करने से ढेर में उपयुक्त जगह से (यानी वर्तमान मूल्य प्राप्त करने के बजाय)।

उत्तर

10

नहीं; मुझे विश्वास नहीं है कि यह है; यदि आप इसे कैश करना चाहते हैं, तो आपको 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; 
} 

अर्थात बनाने अभिव्यक्ति की संख्या पैरामीटर, और वास्तविक लोगों (बल्कि अभिव्यक्ति में किया जा रहा स्थिरांक की तुलना में) कार्यावधि में इसे पारित।

+1

हाय मार्क, मैंने कभी इस तरह के अनुकूलन को कभी नहीं मिला है। क्या आप कृपया सलाह दे सकते हैं कि क्या यह पूर्ववर्ती प्रश्नों के कैशिंग को परफॉर्मेंस के मामले में वास्तव में सहायक है? –

1

लैम्ब्डा एक्सपर्सन स्वचालित रूप से कैश नहीं किए जाते हैं। इसके लिए आपको अपने कैशिंग/ज्ञापन एल्गोरिदम को लागू करने की आवश्यकता होगी। संबंधित Stackoverflow प्रश्न की जाँच करें:

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

यह ध्यान रखें कि लैम्ब्डा भाव आलसी सी # में मूल्यांकन कर रहे हैं महत्वपूर्ण है।

संबंधित मुद्दे