2011-03-18 5 views
5

मैं निर्धारित करने के लिए एक वस्तु एक कोर डाटा से-अनेक संबंध (जो एक NSSet है) में शामिल है कि क्या जरूरत है, और मैं तय करने के लिए जो दो समाधान के लिए बेहतर है कोशिश कर रहा हूँ:कौन सा बेहतर है, एनएसएससेट के पास ऑब्जेक्ट या फास्ट एनम है?

1 समाधान)

if ([managedObject.items containsObject:itemOfInterest]) 
    return … 

समाधान 2)

for (NSManagedObject *item in managedObject.items) 
    if ([item == itemOfInterest]) 
     return … 

समाधान 1 अधिक संक्षिप्त है, लेकिन NSSet वर्ग रेफरी तेजी से गणन NSSet के objectEnumerator तुलना में बेहतर प्रदर्शन कहते हैं। क्या यह शामिल है ऑब्जेक्ट से बेहतर प्रदर्शन करता है?

+0

मुझे यहां कुछ याद आ रहा है लेकिन आपको बिल्कुल खोजने की आवश्यकता क्यों है? यदि आपके पास रिश्ते के प्रत्येक पक्ष पर पहले से ही दोनों वस्तुएं हैं, तो आपके पास पहले से ही आवश्यक जानकारी है। क्या यह एक पारस्परिक संबंध के बिना कई से अधिक रिश्ते या एक से अधिक है? – TechZen

+0

@TechZen: प्रति उपयोगकर्ता के खोज मानदंडों पर एक लाया जाता है। परिणाम एक टेबल में प्रदर्शित होते हैं।उपयोगकर्ता तालिका के माध्यम से इन परिणामों का उपखंड बनाता है। चेकबॉक्स के साथ प्रस्तुत कई रिश्तों के सदस्यों के साथ एक और टेबल है। चेकबॉक्स राज्यों को यह निर्धारित किया जाना चाहिए कि क्या सभी, कोई नहीं, या कुछ चयनित वस्तुओं में उनकी वस्तु है। इसमें बहुत सारी वस्तुएं शामिल हो सकती हैं, इसलिए सबसे कुशल विधि का उपयोग करना महत्वपूर्ण है। मेसर्स रेबॉल्ड और नेपियर की सलाह के लिए धन्यवाद, मुझे विश्वास है कि इसमें ऑब्जेक्ट जाने का रास्ता है। – Wienke

उत्तर

5

मैं हमेशा विकल्प के लिए जाना चाहते हैं 1.

इसकी अधिक संक्षिप्त है, मैं बता सकता है आपके कोड के साथ क्या करने की कोशिश कर और संभावना है कि containsObject कुछ बहुत गंधा अनुकूलन शामिल हैं कि वास्तव में क्या।

20

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

सुविधा के लिए, आप अपने प्रबंधित ऑब्जेक्ट पर -containsFoo: विधि बनाना चाहते हैं, इसलिए आपको जगह पर फ़ेच लॉजिक लिखना नहीं है।

उपरोक्त आपके दो समाधान संक्षेप में अलग हैं। पहला परीक्षण करता है कि संग्रह में कोई ऑब्जेक्ट है कि isEqual: से itemOfInterest पर। आपका दूसरा समाधान परीक्षण करता है कि संग्रह में ऑब्जेक्ट में उसी स्मृति स्थान पर itemOfInterest है। कस्टम isEqual: तर्क वाले ऑब्जेक्ट्स के लिए, ये अलग-अलग परिणाम लौटा सकते हैं। इसका मतलब यह है कि समाधान 2 गैर-मूल डेटा संग्रहों के लिए थोड़ा तेज़ हो सकता है, लेकिन ऐसा इसलिए है क्योंकि आप वास्तव में एक अलग चीज़ का परीक्षण कर रहे हैं, न कि ऑब्जेक्ट गणना के कारण। (हकीकत में, यह केवल छोटे संग्रहों के लिए सच है; नीचे देखें।)

आपको क्यों लगता है कि समाधान 1 -objectEnumerator का उपयोग करता है?

जैसा कि @ जेम्स रेबॉल्ड बताते हैं, आपको आमतौर पर प्रदर्शन कारणों के लिए अंतर्निहित तरीकों को फिर से लिखने की कोशिश नहीं करनी चाहिए। यदि isEqual: समाधान 2 का संस्करण समाधान 1 से तेज़ था, तो क्या आपको नहीं लगता कि ऐप्पल समाधान 2 में कोड का उपयोग कर -containsObject: लागू कर देगा?

असल में, अंतर्निहित CFSet को हैश के रूप में लागू किया गया है, इसलिए रोकथाम की जांच रैखिक के बजाय लॉगरिदमिक है। आम तौर पर, उचित हैश कार्यों के साथ बड़े सेट के लिए, समाधान 1 तेज होगा। CFSet.c में इसके लिए कोड देखें। CFSetContainsValue() देखें। सीएफएसएटी के कार्यान्वयन को निश्चित रूप से रहने की गारंटी नहीं है, लेकिन यह समझने के लिए उपयोगी है कि कोको के भीतर आम तौर पर प्रदर्शन चिंताओं को कैसे संबोधित किया जाता है।

+1

मेरी टिप्पणी को अनदेखा करें - यह आसानी से मैंने कभी भी पढ़े गए सर्वोत्तम उत्तरों में से एक है! –

+0

आपकी गहन प्रतिक्रिया के लिए धन्यवाद। मैंने इससे बहुत कुछ सीखा। प्रश्न में खोज तालिका में प्रबंधित वस्तुओं के चयन पर किया जाता है, जिनकी सामग्री स्वयं एक विशेष fetch अनुरोध का परिणाम होती है। तो मुझे वास्तव में एक और fetch चलाने के बजाय, कैश वस्तुओं के साथ काम करने की जरूरत है। (मैं इस से कई रिश्तों के आधार पर स्टोर से ऑब्जेक्ट खींचते समय "predicateWithFormat: @" किसी भी आइटम ==% @ ", आइटम चयनित" के साथ एक fetch का उपयोग करता हूं।) – Wienke

+0

आपकी स्थिति उचित लगता है, और 'includeObject: ' जेम्स नोट्स के रूप में यहां आपका सबसे अच्छा शर्त है। आप सही हैं कि आपको * फिर से * नहीं लेना चाहिए। और 'includeObject:' 'हैश 'और' isEqual का उपयोग करता है:' जो गलती के लिए दस्तावेज नहीं हैं (आपको इन विधियों को कभी ओवरराइड नहीं करना चाहिए 'NSManagedObject' के लिए)। –

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