2009-02-24 8 views
13

मैं NSSet में संग्रहीत कई ऑब्जेक्ट्स पर एक ही क्रिया करना चाहता हूं।कोको एनएसएआरएआरई/एनएसएसएटी: -मेक ऑब्जेक्ट्सफॉर्मफॉर्मर: बनाम तेज गणना

for (id item in mySetOfObjects) 
    [item action]; 

जो बहुत ठीक काम करता है:

मेरा पहला प्रयास एक तेजी से गणन उपयोग कर रहा था। तब मैंने सोचा:

[mySetOfObjects makeObjectsPerformSelector:@selector(action)]; 

और अब, मुझे नहीं पता कि सबसे अच्छा विकल्प क्या है। जहां तक ​​मैं समझता हूं, दो समाधान बराबर हैं। लेकिन क्या दूसरे पर एक समाधान पसंद करने के लिए तर्क हैं?

उत्तर

21

मैं makeObjectsPerformSelector का उपयोग करने के लिए बहस करता हूं, क्योंकि यह एनएसएसएटी ऑब्जेक्ट को अपनी इंडेक्सिंग, लूपिंग और संदेश प्रेषण की देखभाल करने की अनुमति देता है। एनएसएससेट कोड लिखने वाले लोगों को उस विशेष पाश को लागू करने का सबसे अच्छा तरीका जानने की संभावना है।

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

"अनलोलिंग लूप्स" शीर्षक वाले अनुभाग में ऐप्पल के Code Speed Performance दस्तावेज़ में विषय का संक्षेप में उल्लेख किया गया है।

यदि आप प्रदर्शन के बारे में चिंतित हैं, तो सबसे अच्छी बात यह है कि एक त्वरित प्रोग्राम स्थापित किया गया है जो सेट में ऑब्जेक्ट्स पर कुछ चयनकर्ता करता है। क्या यह कई मिलियन बार चला है, और दो अलग-अलग मामलों के बीच अंतर है।

+0

लिंक के लिए धन्यवाद, मुझे इस दस्तावेज़ को नहीं पता था! जैसा कि आप कहते हैं, "अनलोलिंग लूप" अनुभाग स्पष्ट रूप से बताता है कि कोको डेवलपर्स ने -मेक ऑब्जेक्ट्सफॉर्मफॉर्मर के साथ आंतरिक अनुकूलन किए हैं: – mouviciel

+0

मेरी खुशी। वहां कुछ दिलचस्प चीजें हैं। –

2

makeObjectsPerformSelector: थोड़ा तेज़ हो सकता है, लेकिन मुझे संदेह है कि 99% समय का कोई व्यावहारिक अंतर होने वाला है। हालांकि यह थोड़ा और संक्षिप्त और पठनीय है, मैं इसका कारण उस कारण से उपयोग करूंगा।

4

मैं सरल कारण के लिए makeObjectsPerformSelector का उपयोग नहीं करता क्योंकि यह एक तरह का कॉल है जिसे आप अक्सर नहीं देखते हैं। यहां बताया गया है कि उदाहरण के लिए - मुझे डीबगिंग कोड जोड़ने की आवश्यकता है क्योंकि सरणी की गणना की गई है, और आप वास्तव में makeObjectsPerformSelector के साथ ऐसा नहीं कर सकते हैं जब तक आप यह नहीं बदलते कि कोड रिलीज़ मोड में कैसे काम करता है जो वास्तविक संख्या नहीं है।

for (id item in mySetOfObjects) 
{ 
    #if MY_DEBUG_BUILD 
    if ([item isAllMessedUp]) 
     NSLog(@"we found that wily bug that has been haunting us"); 
    #endif 

    [item action]; 
} 

टॉम

7

मैं भी इस सवाल के साथ पेश किया गया। मैं निम्नलिखित एप्पल डॉक्स में "Sets: Unordered Collections of Objects" के तहत "संग्रह विषय प्रोग्रामिंग" लगता है:

NSSet विधि objectEnumerator आप सेट एक एक के बाद के तत्वों को पार कर सकते हैं। और themakeObjectsPerformSelector: और makeObjectsPerformSelector: withObject: विधियां सेट में अलग-अलग ऑब्जेक्ट्स को संदेश भेजने के लिए प्रदान करती हैं। अधिकांश मामलों में, तेज़ गणना का उपयोग किया जाना चाहिए क्योंकि यह तेजी से और अधिक एनएसईएन्यूमेरेटर या को बनाने के लिए लचीला है MakeObjectsPerformSelector: विधि। गणना के बारे में अधिक जानकारी के लिए, देखें "गणना: संग्रह के तत्वों को स्थानांतरित करना।"

इससे मुझे विश्वास होता है कि फास्ट गणना अभी भी इस एप्लिकेशन के लिए सबसे प्रभावी माध्यम है।

1

यदि शुद्ध गति एकमात्र मुद्दा है (यानी आप कुछ प्रतिपादन इंजन बना रहे हैं जहां हर छोटे सीपीयू चक्र की गणना होती है), किसी भी एनएससीओलेक्शन ऑब्जेक्ट्स (आईओएस 5.0 ~ 6.0 के रूप में) के माध्यम से फिर से शुरू करने का सबसे तेज़ संभव तरीका है विभिन्न "enumerateObjectsUsingBlock" विधियों। मुझे नहीं पता कि यह क्यों है, लेकिन मैंने इसका परीक्षण किया और यह मामला प्रतीत होता है ...

मैंने सैकड़ों हजारों ऑब्जेक्ट्स के छोटे परीक्षण संग्रह संग्रह लिखे हैं जिनमें प्रत्येक के पास एक विधि है जो चींटियों की एक साधारण सरणी है । उन संग्रहों में से प्रत्येक को विभिन्न प्रकार के पुनरावृत्ति (लूप, तेज़ गणना, मेक ऑब्जेक्ट्सफॉर्मफॉर्मर, और एन्युमेरेट ऑब्जेक्ट्स यूजिंगब्लॉक) के लिए कई बार प्रदर्शन करने के लिए मजबूर किया गया था, और लगभग हर मामले में "enumerateObjectsUsingBlock" विधियों ने परीक्षण के दौरान आसानी से जीत हासिल की।

केवल समय था जब यह सच नहीं था जब स्मृति को भरने के लिए शुरू कर दिया, जिसके बाद यह "makeObjectsPerformSelector" को खोना शुरू कर दिया (जब मैं लाखों लोगों की वस्तुओं की साथ इसे चलाने के लिए शुरू कर दिया)।

मुझे खेद है कि मैंने कोड का एक स्नैपशॉट नहीं लिया है, लेकिन यह चलाने के लिए एक बहुत ही सरल परीक्षण है, मैं अत्यधिक कोशिश करता हूं कि आप इसे आज़माएं और देखें। :)

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