2015-06-12 5 views
6

मुझे यह जानकर उत्सुकता है कि स्विफ्ट 1.2 कंपाइलर खाली बंद करने का अनुकूलन करता है या नहीं। क्या निम्नलिखित दो कथन समकक्ष हैं?स्विफ्ट कंपाइलर खाली बंद करने का अनुकूलन करता है?

1:

self.presentViewController(alertController, animated: true) {} 

2:

self.presentViewController(alertController, animated: true, completion: nil) 

धन्यवाद!

+0

डुनो स्वयं निश्चित रूप से, लेकिन आप एक्सकोड में जेनरेट की गई असेंबली को देखकर पता लगा सकते हैं। – rickster

+0

मुझे यकीन नहीं है कि वैध अनुकूलन होगा। 1 एक बंद है जो कुछ भी नहीं करता है, wheres 2 बिल्कुल बंद नहीं करता है। कोई बंद करने का मतलब "डिफ़ॉल्ट व्यवहार का उपयोग नहीं करना" हो सकता है, लेकिन एक खाली बंद करने का अर्थ है "कुछ भी नहीं" जो आवश्यक नहीं है। – Ferruccio

उत्तर

5

रूप @rickster का सुझाव दिया, मैं इस फ़ाइल (simple.swift) के उत्पन्न 86 विधानसभा पर एक नज़र था:

func thingWithClosure(a: Int, b: (() -> Void)?) { 
    println(a) 
    b?() 
} 


thingWithClosure(3) { 
    println("i'm a closure") 
} 

thingWithClosure(5, nil) 

thingWithClosure(2) {} 

मेरे विधानसभा सुंदर जंग लगी है, लेकिन मैं थोड़े थोड़ा इसे भेंगापन कर सकते हैं। ..

unoptimized उत्पन्न x86 विधानसभा के मुख्य अनुभाग, या यह कम से कम हिस्सा है, इस तरह दिखता है:

callq _swift_once 
    movq __TZvO[email protected]GOTPCREL(%rip), %rax 
    movq -64(%rbp), %rcx 
    movq %rcx, (%rax) 
    leaq l_metadata+16(%rip), %rdi 
    movl $32, %r9d 
    movl %r9d, %eax 
    movl $7, %r9d 
    movl %r9d, %edx 
    movq %rax, %rsi 
    movq %rdx, -80(%rbp) 
    movq %rax, -88(%rbp) 
    callq _swift_allocObject 
    leaq __TF6simpleU_FT_T_(%rip), %rcx 
    movq %rcx, 16(%rax) 
    movq $0, 24(%rax) 
    leaq __TPA__TTRXFo__dT__XFo_iT__iT__(%rip), %rcx 
    movq %rcx, -16(%rbp) 
    movq %rax, -8(%rbp) 
    movq -16(%rbp), %rsi 
    movl $3, %r9d 
    movl %r9d, %edi 
    movq %rax, %rdx 
     --> callq __TF6simple16thingWithClosureFTSiGSqFT_T___T_ 
    movq $0, -24(%rbp) 
    movq $0, -32(%rbp) 
    movl $5, %r9d 
    movl %r9d, %edi 
    movq -72(%rbp), %rsi 
    movq -72(%rbp), %rdx 
     --> callq __TF6simple16thingWithClosureFTSiGSqFT_T___T_ 
    leaq l_metadata2+16(%rip), %rdi 
    movq -88(%rbp), %rsi 
    movq -80(%rbp), %rdx 
    callq _swift_allocObject 
    leaq __TF6simpleU0_FT_T_(%rip), %rcx 
    movq %rcx, 16(%rax) 
    movq $0, 24(%rax) 
    leaq __TPA__TTRXFo__dT__XFo_iT__iT__3(%rip), %rcx 
    movq %rcx, -48(%rbp) 
    movq %rax, -40(%rbp) 
    movq -48(%rbp), %rsi 
    movl $2, %r9d 
    movl %r9d, %edi 
    movq %rax, %rdx 
     --> callq __TF6simple16thingWithClosureFTSiGSqFT_T___T_ 
    xorl %eax, %eax 
    addq $96, %rsp 
    popq %rbp 
    retq 
    .cfi_endproc 

मैं ने बताया गया है जहां समारोह 012,391,031 के साथ कहा जाता है। प्रत्येक callq निर्देश से कुछ निर्देश देख रहे हैं, आप देख सकते हैं कि a तर्क r9d रजिस्टर में स्थानांतरित हो गया है।

इसी तरह, अनुकूलित उत्पादन:

callq _swift_once 
    movq __TZvO[email protected]GOTPCREL(%rip), %rax 
    movq %r14, (%rax) 
    movq $3, -24(%rbp) 
    movq [email protected](%rip), %rbx 
    addq $8, %rbx 
    leaq -24(%rbp), %rdi 
    movq %rbx, %rsi 
    callq __TFSs7printlnU__FQ_T_ 
    leaq L___unnamed_1(%rip), %rax 
    movq %rax, -48(%rbp) 
    movq $13, -40(%rbp) 
    movq $0, -32(%rbp) 
    movq [email protected](%rip), %rsi 
    addq $8, %rsi 
    leaq -48(%rbp), %rdi 
     --> callq __TFSs7printlnU__FQ_T_ 
    movq $5, -56(%rbp) 
    leaq -56(%rbp), %rdi 
    movq %rbx, %rsi 
     --> callq __TFSs7printlnU__FQ_T_ 
    movq $2, -64(%rbp) 
    leaq -64(%rbp), %rdi 
    movq %rbx, %rsi 
     --> callq __TFSs7printlnU__FQ_T_ 
    xorl %eax, %eax 
    addq $48, %rsp 
    popq %rbx 
    popq %r14 
    popq %rbp 
    retq 
    .cfi_endproc 

यहाँ, संकलक समारोह inlined है, तो मैं --> बजाय साथ println कॉल ने बताया है।

मैंने एक अनुरूपित 16-बिट सीपीयू साल पहले x86 असेंबली का परिचय लिया था, इसलिए मैं नाटक करने वाला नहीं हूं कि मुझे पता है कि वास्तव में क्या हो रहा है, लेकिन ऐसा लगता है कि -O के साथ संकलित होने पर, कंपाइलर लगभग बराबर समकक्ष कोड उत्सर्जित करता है (निर्देश गणना के संदर्भ में, लेकिन शायद स्मृति लुकअप के मामले में नहीं, आदि)। ऐसा लगता है कि println पर कॉल leaq (लोड प्रभावी पता) निर्देशों के साथ छेड़छाड़ की गई हैं, इसलिए हम सभी जगहों पर कूद सकते हैं, लेकिन मुझे यकीन नहीं है कि (कहां अधिक निर्देश हो सकते हैं? स्थिर डेटा लोड हो सकता है?), या अगर यह मायने रखता है।

अप्रत्याशित संस्करण nil पैरामीटर केस के लिए अधिक से अधिक निर्देश उत्सर्जित करता है, इसलिए प्रमुख अंतर डीबग प्रदर्शन हो सकता है।

बेशक, यह x86 है, इसलिए यह एआरएम पर पूरी तरह से अलग हो सकता है .... शायद एआरएम असेंबली, एलएलवीएम आईआर, या स्विफ्ट आईआर आउटपुट अधिक प्रकाश डालेगा?

यदि कोई बेहतर समझ वाला कोई भी व्यक्ति स्पष्ट कर सकता है, तो मैं खुशी से इस उत्तर को अपडेट कर दूंगा।

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