2011-02-13 13 views
5

सामान्य short-circuit evaluation question के बाद, शून्य ऑब्जेक्ट्स के विरुद्ध बनाए गए और भेजे गए पैरामीटर के लिए शॉर्ट-सर्किट मूल्यांकन कार्य करता है? उदाहरण:उद्देश्य-सी वस्तुओं के लिए संदेशों के लिए शॉर्ट-सर्किट मूल्यांकन का उपयोग करता है?

NSMutableArray *nil_array = nil; 
.... 
[nil_array addObject:[NSString stringWithFormat:@"Something big %@", 
    function_that_takes_a_lot_of_time_to_compute()]]; 

कि धीमी गति से समारोह के नाम से जाना जा रहा या पूरे addObject कॉल मापदंडों के प्रसंस्करण के बिना बाहर अनुकूलित किया जाएगा है?

+3

खुद को खोजने के लिए डीबगर से बहुत डरते हैं? :-) –

+0

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

उत्तर

9

एक ऑब्जेक्ट पॉइंटर को हमेशा एक संदेश भेजा जाता है, भले ही यह किसी ऑब्जेक्ट को इंगित करता है या nil पर इंगित करता है। इसके अतिरिक्त, रनटाइम में संदेश भेजे जाते हैं और इसलिए संकलक केवल nil_array मान नहीं सकते हैं वास्तव में nil है और इसे अनुकूलित करें। क्या होगा यदि प्रारंभिकता ने कुछ और किया, और nil_array एक उदाहरण साबित हुआ?

इसका मतलब है कि आपके द्वारा किए गए सभी अभिव्यक्तियों को आपके तरीकों के लिए तर्क के रूप में पारित किया जाएगा, ताकि किसी भी प्रकार की शॉर्ट-सर्किटिंग न हो। आपका धीमा कार्य निष्पादित किया जाएगा, और यदि इसमें काफी समय लगता है तो यह आपके प्रोग्राम के प्रदर्शन को प्रभावित करेगा।

संपादित करें: मैंने बस इसके बिल्ली (खाली उद्देश्य-सी कमांड लाइन प्रोग्राम) के लिए थोड़ा परीक्षण केस चाबुक किया। यदि आप इसे चलाते हैं और डीबगर कंसोल का निरीक्षण करते हैं, तो आप देखेंगे कि सभी तीन कॉलों से आउटपुट function_that_takes_a_lot_of_time_to_compute() पर दिखाई देता है (5-सेकंड अंतराल में), जबकि केवल t1 और t3 के test: विधियों से आउटपुट दिखाई देता है - स्वाभाविक रूप से, इनके बाद से nil नहीं हैं।

main.m

#import "Test.h" 

int function_that_takes_a_lot_of_time_to_compute(void) 
{ 
    static int i = 1; 

    sleep(5); 
    NSLog(@"%d", i); 

    return i++; 
} 

int main(int argc, const char *argv[]) 
{ 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

    Test *t1 = [[Test alloc] init], *t2 = nil, *t3 = [[Test alloc] init]; 

    [t1 test:function_that_takes_a_lot_of_time_to_compute()]; 
    [t2 test:function_that_takes_a_lot_of_time_to_compute()]; // nil 
    [t3 test:function_that_takes_a_lot_of_time_to_compute()]; 

    [t1 release]; 
    [t3 release]; 

    [pool drain]; 
    return 0; 
} 

Test.h

@interface Test : NSObject {} 

- (void)test:(int)arg; 

@end 

Test.m

@implementation Test 

- (void)test:(int)arg 
{ 
    NSLog(@"Testing arg: %d", arg); 
} 

@end 

आउटपुट

 
1 
Testing arg: 1 
2 
3 
Testing arg: 3 
6

स्वीकार किए जाते हैं जवाब एक अच्छा एक है, लेकिन मैं जोड़ना चाहते थे:

function_that_takes_a_lot_of_time_to_compute() या +[NSString stringWithFormat:] दुष्प्रभाव हो सकते हैं, इसलिए भले ही हम 100% निश्चितता के साथ पता था कि nil_arraynil था (और हम कभी-कभी स्थिर विश्लेषण के माध्यम से इसे जानते हैं), कार्यक्रम को अभी भी function_that_takes_a_lot_of_time_to_compute() और +[NSString stringWithFormat:] निष्पादित करना होगा ताकि यह सुनिश्चित किया जा सके कि यह अपेक्षाकृत व्यवहार कर रहा था।

यदि कोई फ़ंक्शन f() का कोई साइड इफेक्ट नहीं है, तो इसे "शुद्ध" माना जाता है। इसका मतलब यह है कि यह इनपुट तर्क ले सकता है और एक मूल्य वापस कर सकता है, लेकिन यह कभी भी गैर-शुद्ध कार्यों को नहीं बुलाता है और कभी भी कार्यक्रम या वैश्विक स्मृति के किसी भी हिस्से को संशोधित नहीं करता है (तर्क पारित करने में शामिल स्मृति और वापसी मूल्य यहां गिनती नहीं है।) निम्नलिखित समारोह, उदाहरण के लिए, "शुद्ध" है:

int munge(float foo, char bar) { 
    unsigned short quux = bar << 4; 
    return foo + quux; 
} 

सी मानक पुस्तकालय के भीतर शुद्ध फ़ंक्शन के उदाहरण memcmp() और strlen() हैं।

हैं और केवल यदि एक समारोह शुद्ध होने के लिए जाना जाता है, संकलक सुरक्षित रूप से यह करने के लिए कॉल दूर का अनुकूलन कर सकता है, के बाद से नहीं बुला यह कार्यक्रम के बाकी पर कोई प्रभाव नहीं होगा। हालांकि, जीसीसी इसे करने के बारे में बहुत रूढ़िवादी है, और आम तौर पर (हमेशा?) केवल तभी होता है जब फ़ंक्शन शुद्ध चिह्नित होता है, __attribute__((__pure__)) फ़ंक्शन घोषणा पर सजावट के माध्यम से।

एक समारोह शुद्ध है, और इसके अलावा में कभी नहीं संकेत dereferences और कभी अपने ढेर फ्रेम से बाहर किसी भी स्मृति तक पहुँचता है, तो इसके बजाय जीसीसी, जो भी आगे स्थिर विश्लेषण और अनुकूलन की अनुमति देता है में __attribute__((__const__)) चिह्नित किया जा सकता।

+0

+1 मैं साथ नहीं आ सकता था। – BoltClock

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