2010-08-15 12 views
14

मेरे ऐप में UISearchBar है जो उपयोगकर्ता को खोजशब्दों को दर्ज करने की इजाजत देता है। खोज कुंजी परिवर्तन में पाठ के रूप में परिणाम प्रदर्शित करने के लिए प्रत्येक कीस्ट्रोक एक कोर डेटा क्वेरी निष्पादित करता है।कोर डेटा प्रदर्शन में सुधार कैसे करें?

समस्या यह है कि खोज बार कीस्ट्रोक बहुत खराब हैं ... निश्चित रूप से धीमी गति से लाने की वजह से। किसी भी विचार प्रदर्शन को सुधारने के लिए कैसे?

मेरा कोर डेटा एसक्लाइट डेटा स्टोर के साथ समर्थित है जिसमें 1000 ऑब्जेक्ट्स हैं।

// searchKeyword is the string appears in UISearchBar 
// Both title and author may contain several words so I can't use BEGINSWITH 
NSPredicate* predicate = [NSPredicate predicateWithFormat:@"(author CONTAINS[c] %@) OR (title CONTAINS[c] %@)", searchKeyword, searchKeyword]; 

NSEntityDescription* entity = [NSEntityDescription entityForName:@"Book" inManagedObjectContext:managedObjectContext]; 

NSFetchRequest* request = [[NSFetchRequest alloc] init]; 
[request setEntity:entity]; 
[request setPredicate:predicate]; 
[request setFetchLimit:10]; 

NSSortDescriptor* sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"title" ascending:YES]; 
NSArray* sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil]; 
[request setSortDescriptors:sortDescriptors]; 

[sortDescriptor release]; 
[sortDescriptors release]; 

execute request and fetch the results 
fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request 
           managedObjectContext:managedObjectContext 
           sectionNameKeyPath:nil 
           cacheName:nil]; 
NSError* error = nil; 
BOOL success = [fetchedResultsController performFetch:&error]; 
[request release]; 

उत्तर

18

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

इस मेज पर आपकी क्वेरी प्रदर्शन करना, लेकिन इसके बजाय का उपयोग करने का शामिल है या BEGINSWITH, जैसे

शब्द> "शब्द" और शब्द < "टैन"

नोट में कुछ करने में पहली स्ट्रिंग है कि वहाँ खोज शब्द, और दूसरा अंतिम शब्द वृद्धि के साथ खोज शब्द है। यह कोर डेटा को खोज करने के लिए SQL अनुक्रमणिका का उपयोग करने की अनुमति देता है।

ऐप्पल में Core Data डब्ल्यूडब्ल्यूडीसी सत्र है जो नमूना कोड समेत इसे समझाता है। नमूना कोड में एक वर्ग होता है जो स्ट्रिंग को सामान्यीकृत करता है (आईई हटा रहा है), और एक यूनिकोड जागरूक तरीके से किसी शब्द के अंतिम अक्षर को बढ़ाता है।

+0

यह एक अच्छा समाधान है! धन्यवाद!! मैं उस सत्र की तलाश करूंगा और इसे यहां पोस्ट करूंगा यदि मुझे यह मिल जाएगा। – Joshua

+1

डायरेक्ट लिंक: http://developer.apple.com/itunes/?destination=adc.apple.com.4092349126.04109539109.4144345613?i=2041584141 हम्म .. मैंने आपकी पोस्ट के लिए एक लंबा समय इंतजार किया। इस बीच मैंने इंटरनेट पर संघर्ष किया, यह मेरा आत्म पाया: डी यह है "डब्ल्यूडब्ल्यूडीसी 2010, आईफोन ओएस पर कोर डेटा प्रदर्शन अनुकूलित करना" 35:06 –

+1

पर क्षमा करें मुझे संबंधित नमूना कोड नहीं मिला (और मैं एक पंजीकृत देव हूं) । क्या आप एक छोटा कोड फिसल सकते हैं? (सामान्यीकरण और चार वृद्धि) – obiwahn

2

आपको (परिणाम सेट पत्र-गांठ से बताया जाता है) पिछले प्रश्नों के लिए एक सूचकांक के लिए में संवर्द्धित एक trie बना सकते हैं। लेकिन यह एक ही क्वेरी के प्रदर्शन में वृद्धि नहीं करेगा। आप कीस्ट्रोक सिस्टम को भी ट्विक कर सकते हैं, प्रत्येक सिंगल कीस्ट्रोक के बाद एक फ़ेच न करें, लेकिन केवल एक कीस्ट्रोक के बाद, जिसके बाद एक अन्य अंतराल को

4

से पहले एक अंतराल (एक सीमा के रूप में) पारित किया गया है, जबकि यह तेज़ नहीं होगा क्वेरी, पृष्ठभूमि थ्रेड में लुकअप डालने से कीस्ट्रोक को लापरवाही से रोक दिया जाएगा।

+1

+1 लेकिन एक समय में केवल एक पृष्ठभूमि क्वेरी निष्पादित करना याद रखें, और प्रत्येक क्वेरी पर नवीनतम खोज स्ट्रिंग प्राप्त करने के लिए याद रखें (या अन्यथा टेक्स्ट फ़ील्ड अपडेट को सहकर्मी करें), और जब तक यूआई दृढ़ता से निष्पादित न हो जाए तो थ्रेड/एनएसओपरेशन प्राथमिकता को कम करें। –

+0

सुझावों के लिए धन्यवाद।मैं वास्तव में मल्टीथ्रेड समाधान से बचने की कोशिश कर रहा हूं लेकिन अगर मैं कोई अन्य विकल्प नहीं रखूंगा तो मैं करूँगा। – Joshua

-1

ऐप शुरू करते समय, एक पूर्ण ट्राई बनाएं, और संपादन करते समय इसे अनुकूलित करें। उस बेवकूफ भविष्यवाणी का प्रयोग न करें। आप केवल 1000 रिकॉर्ड ला रहे हैं, इसलिए इसमें कोई समय नहीं लगेगा।

+0

क्षमा करें, मुझे यकीन नहीं है कि मैं ऐप स्टार्टअप पर पूर्ण परीक्षण कैसे बना सकता हूं। क्या मैं वास्तव में इस तरह के शीर्षक \ लेखक trie अग्रिम में बना सकते हैं? – Joshua

+0

बस इसे - (बूल) एप्लिकेशन में बनाएं: (यूआईपीप्लिकेशंस *) एप्लिकेशन ने किया थाफिशिश लॉन्चिंगविथऑप्शन: (एनएस डिक्शनरी *) लॉन्चऑप्शन –

+0

बेहतर नहीं है कि इसे पूरी तरह से बनाना है, लेकिन जैसा कि मैंने अपने उत्तर में सुझाव दिया है। – rano

13

जबकि अमोयरा की सिफारिश अच्छी है, आपके पास एक डिज़ाइन समस्या भी है।

खोज क्षेत्र में टाइप किए गए पहले अक्षर को कभी डिस्क पर हिट करना चाहिए। पहले पत्र के बाद आपको केवल स्मृति में पहले से मौजूद खोज परिणामों को परिष्कृत करना चाहिए।

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

इसके अलावा, यदि आप पहले से ही स्मृति में मौजूद डेटा पर खोज करने जा रहे हैं (जैसे NSFetchedResultsController में रहना) तो आपकी पूरी खोज केवल स्मृति में वस्तुओं को हिट करनी चाहिए। डिस्क पर जाकर अनावश्यक और बहुत अपमानजनक है।

+1

हाय मार्कस, यह वास्तव में दिलचस्प बिंदु है। लेकिन मुझे लगता है कि उस समाधान के साथ कोई समस्या है। पहले अक्षर के रूप में 'ए' या 'ई' पर क्लिक करने से, संभवतः अधिकांश ऑब्जेक्ट्स डेटाबेस से लाएंगे (यदि सभी नहीं)। बड़े डीबी से निपटने पर इस एकल fetch में स्मृति प्रभाव के बारे में बात नहीं करने में बहुत लंबा समय लग सकता है ... – Joshua

+0

उस स्थिति में कोई फर्क नहीं पड़ता कि आप किस कार्यान्वयन का उपयोग करते हैं। कोर डेटा कंकाल में खींच जाएगा ताकि स्मृति उपयोग जितना संभव हो उतना कम होगा। जैसा कि आप फ़िल्टर करते हैं कि स्मृति उपयोग नीचे जायेगा। समाधान निश्चित रूप से काम करता है क्योंकि मैंने इसे कई बार इस्तेमाल किया है। –

+0

@ मार्कसएस। ज़रारा अच्छा बिंदु, मार्कस, लेकिन आप NSFetchedResultsController के साथ ऐसा कैसे करते हैं? 'FetchedObjects' प्रॉपर्टी केवल पढ़ने योग्य है ... – Mundi

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