2010-09-20 15 views
57

में 'इनलाइन`' का उपयोग एफ # में inline कीवर्ड मुझे लगता है कि मुझे जो कुछ भी उपयोग किया जाता है उससे थोड़ा अलग उद्देश्य है। सी। उदाहरण के लिए, ऐसा लगता है कि यह फ़ंक्शन के प्रकार को प्रभावित करता है ("स्थिर रूप से हल किए गए प्रकार पैरामीटर" क्या हैं? सभी एफ # प्रकार स्थिर रूप से हल नहीं होते हैं?)एफ #

मुझे inline फ़ंक्शंस का उपयोग कब करना चाहिए?

उत्तर

66

inline कीवर्ड इंगित करता है कि किसी फ़ंक्शन परिभाषा को किसी भी कोड में इनलाइन में डाला जाना चाहिए। अधिकांश समय, इस कार्य के प्रकार पर कोई प्रभाव नहीं पड़ेगा। हालांकि, दुर्लभ मामलों में, यह एक ऐसे फ़ंक्शन का कारण बन सकता है जिसमें अधिक सामान्य प्रकार हो, क्योंकि ऐसी बाधाएं हैं जिन्हें .NET में कोड के संकलित रूप में व्यक्त नहीं किया जा सकता है, लेकिन जब फ़ंक्शन को रेखांकित किया जा रहा है तो इसे लागू किया जा सकता है।

प्राथमिक मामला जहां यह लागू होता है ऑपरेटरों का उपयोग होता है।

let add a b = a + b 

एक monomorphic अनुमानित प्रकार होगा (शायद int -> int -> int, लेकिन यह float -> float -> float की तरह कुछ हो सकता है अगर आप कोड के बजाय उस प्रकार में इस समारोह का उपयोग करता है जो है)। हालांकि, इस समारोह इनलाइन चिह्नित करके, एफ # संकलक एक बहुरूपी प्रकार यह निष्कर्ष निकाल देगा:

let inline add a b = a + b 
// add has type ^a -> ^b -> ^c when (^a or ^b) : (static member (+) : ^a * ^b -> ^c) 

वहाँ नेट पर संकलित कोड में एक प्रथम श्रेणी के रास्ते में इस प्रकार की बाधा एन्कोड करने के लिए कोई रास्ता नहीं है। हालांकि, एफ # कंपाइलर इस बाधा को उस साइट पर लागू कर सकता है जहां यह फ़ंक्शन को रेखांकित करता है, ताकि सभी ऑपरेटर उपयोग संकलित समय पर हल हो जाएं।

प्रकार ^a, ^b पैरामीटर, और ^c "स्थिर प्रकार पैरामीटर का समाधान" कर रहे हैं, जिसका अर्थ है कि बहस के प्रकार स्थिर साइट जहां उन मानकों को इस्तेमाल किया जा रहा पर जाना जाता है किया जाना चाहिए। यह सामान्य प्रकार के पैरामीटर के विपरीत है (उदा। 'a, 'b, आदि), जहां पैरामीटर का मतलब कुछ ऐसा है जो "कुछ प्रकार जो बाद में आपूर्ति की जाएगी, लेकिन जो कुछ भी हो सकता है"।

+0

मुझे खेद है, लेकिन मैं सिर्फ एफ # सीखना शुरू कर रहा हूं और मुझे आपका जवाब बिल्कुल समझ में नहीं आ रहा है, क्या आप मुझे कुछ यूआरएल बता सकते हैं जहां आपके द्वारा उपयोग की जाने वाली अवधारणाओं को समझाया गया है? – knocte

+1

'' पी: 'ए'' - यह आवश्यक है कि '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' > कुछबेस टाइप प्रकार, आदि दूसरी तरफ, '' p:^a'' - यह आवश्यक है कि '' p'' एक प्रकार हो जो कोड में आमंत्रण बिंदुओं पर कुछ विशेषताओं या उप प्रकार का समर्थन करता है या एक सहायक मॉड्यूल खोला या एक विस्तार विधियों वर्ग, आदि का उपयोग करके – George

8

F# component design guidelines केवल इसके बारे में थोड़ा सा उल्लेख करें। मेरे सिफारिश (कि अच्छी तरह से वहाँ क्या कहा है के साथ संरेखित) है:

  • का प्रयोग न करें inline
    • अपवाद: आप जब गणितीय पुस्तकालयों लेखन अन्य एफ # कोड से भस्म किया जाना inline विचार कर सकते हैं और आप चाहते हैं विभिन्न संख्यात्मक डेटा प्रकारों पर जेनेरिक कार्यों को लिखने के लिए।

के बहुत सारे हैं अन्य "रोचक" परिदृश्यों कि सी ++ टेम्पलेट्स की तरह एक सा काम की "बतख टाइपिंग" प्रकार के लिए इनलाइन और स्थिर सदस्य कमी के उपयोग करता है। मेरी सलाह है कि प्लेग की तरह उन सभी से बचें।

@ केवीबी का उत्तर 'स्थिर प्रकार की बाधाओं' के बारे में अधिक गहराई में जाता है।

+6

'इनलाइन' कीवर्ड भी गणितीय पुस्तकालयों से परे बेहद उपयोगी है।उदाहरण के लिए, डेटा संरचनाओं के संदर्भ में जहां इसे किसी भी रन-टाइम प्रदर्शन दंड के बिना अमूर्त लोगों से ठोस डेटा संरचनाओं को लिखने के लिए उपयोग किया जा सकता है। –

+0

मुझे इनलाइन के बिना टाइप-क्लासेस को कैसे कार्यान्वित किया जाना चाहिए? –

28

मुझे inline फ़ंक्शंस का उपयोग कब करना चाहिए?

व्यवहार में inline कीवर्ड की सबसे अधिक मूल्यवान आवेदन कॉल साइट जहां उनके कार्य तर्क भी आदेश कोड का एक अकेले पूरी तरह से अनुकूलित टुकड़ा का उत्पादन करने में inlined कर रहे हैं करने के लिए उच्च क्रम कार्यों को इनलाइन है।

उदाहरण के लिए, निम्नलिखित fold समारोह में inline यह 5 × तेजी से बनाता है:

let inline fold f a (xs: _ []) = 
    let mutable a = a 
    for i=0 to xs.Length-1 do 
     a <- f a xs.[i] 
    a 

ध्यान दें कि यह क्या inline सबसे अन्य भाषाओं में करता है के लिए छोटे सादृश्य भालू। आप सी ++ में टेम्पलेट मेटाप्रोग्रामिंग का उपयोग करके एक समान प्रभाव प्राप्त कर सकते हैं लेकिन एफ # संकलित असेंबली के बीच भी इनलाइन कर सकता है क्योंकि inline .NET मेटाडेटा के माध्यम से व्यक्त किया जाता है।

+2

मानक-पुस्तकालय गुना रेखांकित है? –

+5

@ जे कूपर: नहीं, लेकिन यह अपने फ़ंक्शन तर्क को एक अनुकूलित बंद करने में परिवर्तित करता है जो कुछ प्रकारों के लिए मदद करता है। उदाहरण के लिए, जटिल संख्याओं पर लागू होने पर ''fold' मैंने अंतर्निहित 'Array.fold' से ~ 3 × तेज है। –

+0

दिलचस्प। 'इनलाइन' का उपयोग करके अंतर्निहित में नकारात्मकता होगी? –

15

आपको इनलाइन का उपयोग करना चाहिए जब आपको किसी फ़ंक्शन को परिभाषित करने की आवश्यकता होती है जिसमें प्रत्येक प्रकार की साइट पर इसका प्रकार (पुनः) मूल्यांकन किया जाना चाहिए, सामान्य कार्य के विपरीत, जिसका प्रकार केवल मूल्यांकन (अनुमानित) होगा पहले उपयोग की साइट, और फिर उसके बाद हर जगह उस पहले अनुमानित प्रकार हस्ताक्षर के साथ स्थाई रूप से टाइप किया जा रहा है।

इनलाइन मामले में, समारोह परिभाषा है, जबकि सामान्य (कोई नहीं-इनलाइन) मामले में, समारोह स्थिर (और अक्सर परोक्ष) द्वारा लिखा गया है, प्रभावी रूप से सामान्य/बहुरूपी है।

तो, आप इनलाइन, निम्नलिखित कोड का उपयोग करता है, तो:

let inline add a b = a + b 

[<EntryPoint>] 
let main args = 

    let one = 1 
    let two = 2 
    let three = add one two 
    // here add has been compiled to take 2 ints and return an int 

    let dog = "dog" 
    let cat = "cat" 
    let dogcat = add dog cat 
    // here add has been compiled to take 2 strings and return a string 

    printfn "%i" three 
    printfn "%s" dogcat 

    0 

का निर्माण करेगा, और निम्न उत्पादन का उत्पादन करने के लिए संकलन:

3 
dogcat 

दूसरे शब्दों में, एक ही ऐड समारोह परिभाषा है दोनों कार्यों को उत्पन्न करने के लिए प्रयोग किया जाता है जो पूर्णांक में जोड़ता है, और एक फ़ंक्शन जो दो तारों को जोड़ता है (वास्तव में अंतर्निहित ऑपरेटर ओवरलोडिंग + को इनलाइन का उपयोग करके हुड के तहत भी प्राप्त किया जाता है)।

इस कोड जबकि

, सिवाय इसके कि ऐड समारोह नहीं रह घोषित किया जाता है इनलाइन समान:

let add a b = a + b 

[<EntryPoint>] 
let main args = 

    let one = 1 
    let two = 2 
    let three = add one two 
    // here add has been compiled to take 2 ints and return an int 

    let dog = "dog" 
    let cat = "cat" 
    let dogcat = add dog cat 
    // since add was not declared inline, it cannot be recompiled 
    // and so we now have a type mismatch here 

    printfn "%i" three 
    printfn "%s" dogcat 

    0 

संकलन नहीं होगा, इस शिकायत के साथ विफल:

let dogcat = add dog cat 
        ^^^ - This expression was expected to have type int 
          but instead has type string 

जहां इनलाइन उपयोग करने का एक अच्छा उदाहरण उपयुक्त है, जब आप 2 तर्कों के साथ फ़ंक्शन के तर्कों के अनुप्रयोग के क्रम को उल्टा करने के लिए एक सामान्य फ़ंक्शन को परिभाषित करना चाहते हैं, उदाहरण के लिए

let inline flip f x y = f y x 

के रूप में इस सवाल का Different argument order for getting N-th element of Array, List or Seq को @pad से जवाब में किया जाता है।