2016-10-11 16 views
6

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

fn main() { 
    fn local_plus(x: i64, y: i64) -> i64 { 
     x + y 
    } 
    let x = 2i64; 
    let y = 5i64; 

    let local_res = local_plus(x, y); 
    let external_res = external_plus(x,y); 
    assert_eq!(local_res, external_res); 
} 

fn external_plus(x: i64, y: i64) -> i64 { 
    x + y 
} 

मैं अगर वहाँ ऐसा करने का कोई नकारात्मक प्रदर्शन निहितार्थ है सोच रहा था? जैसा कि जंग फंक्शन को दोबारा घोषित करता है या जब भी फ़ंक्शन चलता है तो फ़ंक्शन स्पेस की कुछ अवांछित मात्रा लेता है? या क्या यह सचमुच कोई प्रदर्शन निहितार्थ नहीं है?

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

+1

आप कुछ बेंचमार्क चलाकर या एमआईआर/असेंबली आउटपुट की जांच करके इसे स्वयं पा सकते हैं। – ljedrz

+0

@ljedrz: बेंचमार्क फिकल जानवर हैं, सबसे अच्छी तरह से अप्रचलित और अनुकूलित एमआईआर/एलएलवीएम आईआर/असेंबली की जांच करें। –

+0

@MatthieuM। सहमत - बेंचमार्क अधिक जटिल मामलों के लिए बेहतर अनुकूल हैं जहां अन्य तरीके अब व्यावहारिक नहीं हैं। – ljedrz

उत्तर

5

कोई प्रभाव नहीं है; मैंने दोनों प्रकारों के लिए उत्पन्न असेंबली की जांच की और यह समान है।

दो संस्करणों मैं तुलना में:

"बाहरी":

fn main() { 
    let x = 2i64; 
    let y = 5i64; 

    let external_res = external_plus(x,y); 
} 

fn external_plus(x: i64, y: i64) -> i64 { 
    x + y 
} 

"स्थानीय":

fn main() { 
    fn local_plus(x: i64, y: i64) -> i64 { 
     x + y 
    } 
    let x = 2i64; 
    let y = 5i64; 

    let local_res = local_plus(x, y); 
} 

और दोनों (आज के रात में रिलीज़ मोड) एक ही एएसएम परिणाम उपज :

.text 
    .file "rust_out.cgu-0.rs" 
    .section .text._ZN8rust_out4main17hb497928495d48c40E,"ax",@progbits 
    .p2align 4, 0x90 
    .type _ZN8rust_out4main17hb497928495d48c40E,@function 
_ZN8rust_out4main17hb497928495d48c40E: 
    .cfi_startproc 
    retq 
.Lfunc_end0: 
    .size _ZN8rust_out4main17hb497928495d48c40E, .Lfunc_end0-_ZN8rust_out4main17hb497928495d48c40E 
    .cfi_endproc 

    .section .text.main,"ax",@progbits 
    .globl main 
    .p2align 4, 0x90 
    .type main,@function 
main: 
    .cfi_startproc 
    movq %rsi, %rax 
    movq %rdi, %rcx 
    leaq _ZN8rust_out4main17hb497928495d48c40E(%rip), %rdi 
    movq %rcx, %rsi 
    movq %rax, %rdx 
    jmp [email protected] 
.Lfunc_end1: 
    .size main, .Lfunc_end1-main 
    .cfi_endproc 


    .section ".note.GNU-stack","",@progbits 

जिसका अर्थ है जेनरेट बाइनरी में शून्य अंतर (न केवल प्रदर्शन-वार) होगा।

और क्या है, इससे कोई फर्क नहीं पड़ता कि आप किसी फ़ंक्शन का उपयोग करते हैं; निम्नलिखित दृष्टिकोण:

fn main() { 
    let x = 2i64; 
    let y = 5i64; 

    let res = x + y; 
} 

भी वही असेंबली उत्पन्न करता है।

नीचे की रेखा यह है कि, सामान्य रूप से, फ़ंक्शंस इनलाइनों के बारे में बताए जाते हैं कि आप उन्हें main() या उसके बाहर घोषित करते हैं या नहीं।

संपादित: के रूप में Shepmaster ने कहा, इस कार्यक्रम में कोई दुष्प्रभाव होते हैं, इसलिए दोनों वेरिएंट के लिए उत्पन्न विधानसभा वास्तव में के लिए एक के रूप में एक ही है:

fn main() {} 

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

+2

मुझे पूरा यकीन है कि अनुकूलक प्रोग्राम में सब कुछ हटा रहा है, क्योंकि इसमें कोई अवलोकन दुष्प्रभाव नहीं है। 'res' पूरी तरह से अप्रयुक्त है, इसलिए मुझे लगता है कि आप इसे 'fn main() {}' के लिए देखेंगे। – Shepmaster

+0

@ शेमपस्टर टीआईएल :)। मैं इसे उत्तर में जोड़ दूंगा। – ljedrz

6

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

क्या आप the Rust playground के बारे में जानते हैं?

अपना कोड दर्ज करें, "रन" के बजाय "एलएलवीएम आईआर", "असेंबली" या "एमआईआर" पर क्लिक करें, और आप देखेंगे कि कोड के लिए उत्सर्जित निम्न-स्तर का प्रतिनिधित्व क्या है।

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

मैं सोच रहा था कि ऐसा करने का कोई नकारात्मक प्रदर्शन निहितार्थ है या नहीं?

एक बहुत जटिल सवाल है कि; वास्तव में।

केवल जंग में स्थानीय रूप से या बाहर से एक समारोह की घोषणा के बीच का अंतर गुंजाइश से एक है। इसे स्थानीय रूप से घोषित करने से बस इसका दायरा कम हो जाता है। कुछ और नहीं

हालांकि ... गुंजाइश, और उपयोग, संकलन पर कठोर प्रभाव हो सकता है।

एक समारोह है कि उदाहरण के लिए केवल एक बार इस्तेमाल, अधिकांशतः एक समारोह है कि 10 बार प्रयोग किया जाता है की तुलना में inlined होने की संभावना है। एक कंपाइलर आसानी से pub फ़ंक्शन (असंबद्ध) के उपयोग की संख्या का आकलन नहीं कर सकता है, लेकिन स्थानीय या गैर -फ़ंक्शंस के लिए सही ज्ञान है। और क्या कोई फ़ंक्शन रेखांकित है या नहीं, प्रदर्शन प्रोफ़ाइल को प्रभावित कर सकता है (बदतर या बेहतर के लिए)।

तो, गुंजाइश को कम करने, और इस तरह के उपयोग को सीमित करके, आप संकलक प्रोत्साहित कर रहे हैं इनलाइन किए जाने वाले अपने कार्य पर विचार करना (अपनी छाप जब तक यह "ठंड")।

दूसरी ओर, के बाद से गुंजाइश कम हो जाता है, इसे साझा नहीं किया जा सकता है (जाहिर है)।

तो ... क्या?

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

यह कैप्सूलीकरण है।

जंग में कुछ विश्वास है, यह भूमि के ऊपर शुरू नहीं की जाएगी कि यह यह बच सकते हैं।

+0

महान जवाब! हालांकि मामूली नाइटपिक: शायद आप तनाव देना चाहते हैं कि कोई * प्रत्यक्ष * प्रभाव नहीं है। उदाहरण के लिए, जावा में कुछ प्रकार के "आंतरिक वर्ग" होते हैं जो स्वचालित रूप से बाहरी के संदर्भ में होते हैं। जंग के बंद होने के साथ ही (बस बोल रहा है)। तो मैं कहूंगा कि यह स्पष्ट करना महत्वपूर्ण है कि आंतरिक कार्य उनके संलग्न कार्य से कुछ भी संदर्भित नहीं करते हैं और संलग्न कार्य के ढेर-स्थान को नहीं लेते हैं। इनलाइनिंग पर केवल * अप्रत्यक्ष * प्रभाव। –

+0

@ लुकासकल्बर्टोड: मैंने यहां कुछ बोल्ड जोड़े। मैं इस बात को प्रभावित करने के लिए अनिच्छुक हूं कि इससे क्या प्रभावित नहीं होता है क्योंकि मुझे डर है कि इससे लोगों को यह सोचने में मदद मिल सकती है कि अगर यह सूची में नहीं है तो यह प्रभावित हो गया है, इसलिए इसके बजाय मैंने जोर दिया (अधिक) कि यह केवल दायरे को प्रभावित करता है और कुछ भी नहीं। –

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

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