पहले मैं ListControl
बदलूंगा कि आपके डेटा स्रोत को कैसे देखता है, आप परिणाम IEnumerable<string>
को परिवर्तित कर रहे हैं List<string>
। खासकर जब आपने कुछ अक्षर टाइप किए हैं तो यह अक्षम (और अनावश्यक) हो सकता है। अपने डेटा की विस्तृत प्रतियां न बनाएं ।
- मैं
.Where()
एक संग्रह के लिए परिणाम को लपेटता हूं जो केवल उसी चीज को लागू करता है जो IList
(खोज) से आवश्यक है । यह आपको प्रत्येक वर्ण के लिए एक नई बड़ी सूची बनाने के लिए बचाएगा।
- विकल्प के रूप में मैं LINQ से बचूंगा और मैं कुछ और विशिष्ट (और अनुकूलित) लिखूंगा। अपनी सूची को स्मृति में रखें और मिलान किए गए सूचकांकों की एक सरणी बनाएं, सरणी का पुन: उपयोग करें ताकि आपको प्रत्येक खोज के लिए इसे पुनः प्राप्त न करना पड़े।
दूसरा कदम बड़ी सूची में खोज नहीं करना है जब छोटा एक पर्याप्त है। जब उपयोगकर्ता ने "एब" टाइप करना शुरू कर दिया और उसने "सी" जोड़ दिया तो आपको बड़ी सूची में शोध करने की आवश्यकता नहीं है, फ़िल्टर की गई सूची में खोज पर्याप्त (और तेज) है। हर बार खोज को परिष्कृत करें, हर बार पूर्ण खोज न करें।
तीसरा चरण कठिन हो सकता है: जल्दी खोजे जाने के लिए व्यवस्थित डेटा रखें । अब आपको अपने डेटा को संग्रहीत करने के लिए आपके द्वारा उपयोग की जाने वाली संरचना को बदलना होगा। इस तरह एक पेड़ की कल्पना करो:
एबीसी
बेहतर छत जोड़ें
बोन कंटूर के ऊपर
यह केवल एक सरणी के साथ लागू किया जा सकता है (यदि आप एएनएसआई नामों के साथ काम कर रहे हैं अन्यथा एक शब्दकोश बेहतर होगा)। इस तरह सूची बनाएँ (चित्रण के उद्देश्य, यह स्ट्रिंग की शुरुआत से मेल खाता है):
var dictionary = new Dictionary<char, List<string>>();
foreach (var user in users)
{
char letter = user[0];
if (dictionary.Contains(letter))
dictionary[letter].Add(user);
else
{
var newList = new List<string>();
newList.Add(user);
dictionary.Add(letter, newList);
}
}
पहले वर्ण का उपयोग करके खोज की जाएगी:
char letter = textBox_search.Text[0];
if (dictionary.Contains(letter))
{
listBox_choices.DataSource =
new MyListWrapper(dictionary[letter].Where(x => x.Contains(textBox_search.Text)));
}
कृपया ध्यान दें कि मैं MyListWrapper()
पहले चरण में सुझाव के रूप में इस्तेमाल किया गया था (लेकिन मैं संक्षिप्तता के लिए 2 सुझाव द्वारा छोड़ा गया था, यदि आप शब्दकोश कुंजी के लिए सही आकार चुनते हैं तो आप प्रत्येक सूची को छोटा और तेज़ रख सकते हैं - शायद - और कुछ भी बचने के लिए)। इसके अलावा ध्यान दें कि आप अपने शब्दकोश के लिए पहले दो वर्णों का उपयोग करने की कोशिश कर सकते हैं (अधिक सूचियाँ और छोटी)। यदि आप इसे बढ़ाते हैं तो आपके पास एक पेड़ होगा (लेकिन मुझे नहीं लगता कि आपके पास इतनी बड़ी संख्या में आइटम हैं)।
कर रहे हैं कई अलग अलग एल्गोरिदम स्ट्रिंग खोज (संबंधित डेटा संरचनाओं के साथ) के लिए बस कुछ ही उल्लेख करने के लिए,:
- परिमित राज्य ऑटोमेटोन आधारित खोज : इस दृष्टिकोण में, हम एक नियतात्मक परिमित ऑटोमेटन (डीएफए) का निर्माण करके पीछे हटने से बचते हैं जो संग्रहीत खोज स्ट्रिंग को पहचानता है। ये निर्माण के लिए महंगे हैं - वे आमतौर पर पावरसेट निर्माण का उपयोग करके बनाए जाते हैं - लेकिन उपयोग करने के लिए बहुत जल्दी हैं।
- स्टब्स : नथ-मॉरिस-प्रैट एक डीएफए की गणना करता है जो एक प्रत्यय के रूप में खोज करने के लिए स्ट्रिंग के साथ इनपुट को पहचानता है, बॉयर-मूर सुई के अंत से खोजना शुरू कर देता है, इसलिए यह आमतौर पर प्रत्येक चरण में पूरी सुई-लंबाई से आगे कूद सकता है। Baeza-Yates इस बात पर नज़र रखती है कि क्या पिछले j अक्षर खोज स्ट्रिंग का उपसर्ग थे, और इसलिए यह फ़ज़ी स्ट्रिंग खोज के लिए अनुकूल है। बिटप एल्गोरिथ्म Baeza-Yates 'दृष्टिकोण का एक अनुप्रयोग है।
- सूचकांक विधियाँ : तेज खोज एल्गोरिदम पाठ के प्रीप्रोसेसिंग पर आधारित हैं। एक विकल्प सूचकांक के निर्माण के बाद, उदाहरण के लिए एक प्रत्यय वृक्ष या प्रत्यय सरणी, एक पैटर्न की घटनाओं को जल्दी से पाया जा सकता है।
- अन्य प्रकार : कुछ खोज विधियाँ, उदाहरण के लिए, ट्रिग्राम खोज, का उद्देश्य "मेल / न-मैच" के बजाय खोज स्ट्रिंग और पाठ के बीच एक "निकटता" स्कोर खोजना है। इन्हें कभी-कभी "फ़ज़ी" खोजों कहा जाता है।
समानांतर खोज के बारे में कुछ शब्द। यह संभव है, लेकिन यह शायद ही कभी तुच्छ है क्योंकि इसे समानांतर बनाने के लिए ओवरहेड आसानी से बहुत अधिक हो सकता है जो खुद को खोजते हैं। मैं खुद को समानांतर (विभाजन और तुल्यकालन में खोज नहीं करूंगा) जल्द ही व्यापक और शायद जटिल भी हो जाएगा, लेकिन मैं एक अलग धागे की खोज करूंगा । यदि मुख्य थ्रेड व्यस्त नहीं है, तो आपके उपयोगकर्ता टाइप करते समय किसी भी देरी को महसूस नहीं करेंगे (वे नोट नहीं करेंगे यदि सूची 200 एमएस के बाद दिखाई देगी, लेकिन वे टाइप करने के बाद 50 एमएस इंतजार करना होगा तो वे असहज महसूस करेंगे) । बेशक खोज अपने आप में पर्याप्त तेज़ होनी चाहिए, इस मामले में आप खोज को गति देने के लिए थ्रेड का उपयोग नहीं करते हैं लेकिन अपने UI को उत्तरदायी बनाए रखने के लिए । कृपया ध्यान दें कि एक अलग धागा आपकी क्वेरी नहीं बनाएगातेजी सेयह UI लटकाएगा नहीं, लेकिन यदि आपकी क्वेरी धीमी थी, तब भी यह एक अलग थ्रेड में धीमी होगी (इसके अलावा आपको कई अनुक्रमिक अनुरोधों को संभालना होगा)।
HashSet<T>
आप यहाँ मदद नहीं करेंगे, क्योंकि आप स्ट्रिंग का हिस्सा खोज रहे हैं ।