2010-10-20 15 views
8

अगर मैं एक बड़ी जावास्क्रिप्ट स्ट्रिंग सरणी 10,000 से अधिक तत्व है कि है, मैं जल्दी से उसमें खोज कैसे?बड़े जेएस स्ट्रिंग सरणी के माध्यम से खोज अनुकूलित करें?

अभी मैं, एक जावास्क्रिप्ट स्ट्रिंग सरणी है कि एक नौकरी का विवरण संग्रहीत करता है और मैं "गतिशील फिल्टर लौटे सूची में उपयोगकर्ता की अनुमति के रूप में वे एक इनपुट बॉक्स में टाइप हूँ।

तो कहते हैं कि मेरे पास है इसलिए की तरह एक स्ट्रिंग सरणी:
var descArr = {"flipping burgers", "pumping gas", "delivering mail"};

और उपयोगकर्ता के लिए खोज करना चाहता है: "p"

मैं कैसे एक स्ट्रिंग सरणी जल्दी से उस में 10000+ वर्णन है कि खोज करने के लिए सक्षम हो जाएगा स्पष्ट रूप से मैं विवरण सरणी को सॉर्ट नहीं कर सकता क्योंकि वे विवरण हैं, इसलिए बाइनरी खोज समाप्त हो गई है। और चूंकि उपयोगकर्ता "p" या "pi" या पत्र के किसी भी संयोजन से खोज सकते हैं, इस आंशिक खोज का मतलब है कि मैं (अर्थात searchDescArray["pumping gas"]) खोज में तेजी लाने के साहचर्य सरणियों का उपयोग नहीं कर सकते हैं।

कोई भी विचार किसी को भी?

+1

क्या आप स्ट्रिंग्स या तारों के अंदर की शुरुआत में खोज से मेल खाना चाहते हैं? यदि उपयोगकर्ता "पी" की खोज करता है, तो क्या इसमें परिणामस्वरूप "फ्लिपिंग बर्गर" शामिल होना चाहिए? – Guffa

+1

descArr एक सरणी नहीं बल्कि एक शाब्दिक वस्तु है। –

+0

@guffa, हां, यदि उपयोगकर्ता "पी" की खोज करता है तो इसमें परिणामस्वरूप "फ्लिपिंग बर्गर" शामिल होना चाहिए। मुझे लगता है कि अभी सबसे बड़ी धीमी गति वास्तविक खोज है। वर्तमान में मेरे पास एक लूप है जो सरणी पर पुनरावृत्त करता है और यह तुलना करता है: यदि (descArray [i] .search ("पी"))> -1) {// वापसी परिणाम} – TriFu

उत्तर

18

वास्तविक ब्राउज़रों में रेग्युलर एक्सप्रेशन इंजन के रूप में, गति के मामले में पागल जा रहे हैं कि यह कैसे इस तरह से करने के बारे में? एक सरणी के बजाय एक विशाल स्ट्रिंग पास करें और शब्दों को पहचान के साथ अलग करें। उदाहरण:

  • स्ट्रिंग "flipping burgers""pumping gas""delivering mail"
  • Regex: "([^"]*ping[^"]*)"
वैश्विक आप सभी मैचों पाने के लिए स्विच /g साथ

। सुनिश्चित करें कि उपयोगकर्ता आपके स्ट्रिंग सेपरेटर की खोज नहीं करता है।

तुम भी तरह कुछ के साथ स्ट्रिंग में एक आईडी जोड़ सकते हैं:

  • स्ट्रिंग "11 flipping burgers""12 pumping gas""13 delivering mail"
  • Regex: "(\d+) ([^"]*ping[^"]*)"

  • उदाहरण: http://jsfiddle.net/RnabN/4/ (30000 तार, 100 के लिए सीमा परिणाम)

+0

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

+0

आधुनिक नियमित अभिव्यक्ति रनटाइम लगभग प्रीकंपिल्ड सी ++ प्रोग्राम के जितना तेज़ होते हैं। पुरानी जावास्क्रिप्ट (फ़ायरफ़ॉक्स 2/नेटस्केप/इंटरनेट एक्सप्लोरर) और नए समय-समय पर कार्यान्वयन के बीच प्रदर्शन दुनिया हैं। क्रोम के साथ एक औसत पीसी पर जावास्क्रिप्ट इंटरनेट एक्सप्लोरर के साथ एक highend पीसी पर जावास्क्रिप्ट कई बार तेजी से चलाता है। – sod

+0

यह बिल्कुल विज्ञापन के रूप में काम किया। धन्यवाद। – Saltymule

1

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

साथ ही डेटाबेस लाभ, आपको वेब पर आधारित अंत में इस डेटा (10000 चर) को आउटपुट न करने से भी लाभ होगा - यदि आप केवल उन लोगों को वापस लौटते हैं जिन्हें आप चाहते हैं, तो आप एक उचित बिट बचाएंगे बैंडविड्थ।

+0

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

+0

@e बिजनेस - इसके लिए एक पूर्ण पाठ अनुक्रमणिका की आवश्यकता नहीं होगी। SQL सर्वर पर 'पी%' जैसे WHERE शीर्षक के साथ एक क्वेरी अभी भी SARGable होगी और यदि कोई मौजूद था तो इस कॉलम पर एक अनुक्रमणिका का उपयोग करेगा। यह भी तेज़ है क्योंकि आप प्रोसेसिंग से पहले सभी 10000 तार को क्लाइंट में ट्रांसमिट नहीं कर रहे हैं, केवल कट डाउन सूची। – Paddy

+0

3 साल के लिए सोचने के बाद, यह आपका सबसे अच्छा रिटॉर्ट है?% पी% sargable नहीं है, और मुझे विश्वास है कि पूछताछ क्या चाहता था। – aaaaaaaaaaaa

0

मैं एक तैयार जे एस समारोह, jQuery से autocomplete कोशिश कर उदाहरण के लिए सुझाव देते हैं। यह तेज़ है और इसमें कॉन्फ़िगर करने के कई विकल्प हैं।

चेक बाहर jQuery autocomplete demo

+0

हाय मेडोपोल, सुझाव के लिए धन्यवाद लेकिन JQuery स्वत: पूर्णता केवल तभी तेज होती है जब अपेक्षाकृत कुछ प्रविष्टियां होती हैं, जब 10 के + के क्रम में यह धीमा हो जाता है – TriFu

4

कोई गति करने का कोई तरीका नहीं है n कुछ बदलाव किए बिना प्रारंभिक सरणी लुकअप। आप परिणामों को कैश करके और गतिशील रूप से पैटर्न पर मैप करके निरंतर लुकअप को तेज कर सकते हैं।

1.) अपने डेटा प्रारूप को समायोजित करें। यह प्रारंभिक लुकअप कुछ हद तक तेज बनाता है। असल में, आप precache।

var data = { 
    a : ['Ant farm', 'Ant massage parlor'], 
    b : ['Bat farm', 'Bat massage parlor'] 
    // etc 
} 

2.) सेटअप कैश यांत्रिकी।

var searchFor = function(str, list, caseSensitive, reduce){ 
    str = str.replace(/(?:^\s*|\s*$)/g, ''); // trim whitespace 
    var found = []; 
    var reg = new RegExp('^\\s?'+str, 'g' + caseSensitive ? '':'i'); 
    var i = list.length; 
    while(i--){ 
     if(reg.test(list[i])) found.push(list[i]); 
     reduce && list.splice(i, 1); 
    } 
} 

var lookUp = function(str, caseSensitive){ 
    str = str.replace(/(?:^\s*|\s*$)/g, ''); // trim whitespace 
    if(data[str]) return cache[str]; 
    var firstChar = caseSensitive ? str[0] : str[0].toLowerCase(); 
    var list = data[firstChar]; 
    if(!list) return (data[str] = []); 
    // we cache on data since it's already a caching object. 
    return (data[str] = searchFor(str, list, caseSensitive)); 
} 

3.) एक सटीक वस्तु बनाने के लिए निम्न स्क्रिप्ट का उपयोग करें। मेरा सुझाव है कि आप इसे एक बार चलाएं और एक स्थिर कैश ऑब्जेक्ट बनाने के लिए JSON.stringify का उपयोग करें। (या बैकएंड पर ऐसा)

// we need lookUp function from above, this might take a while 
var preCache = function(arr){ 
    var chars = "abcdefghijklmnopqrstuvwxyz".split(''); 
    var cache = {}; 
    var i = chars.length; 
    while(i--){ 
     // reduce is true, so we're destroying the original list here. 
     cache[chars[i]] = searchFor(chars[i], arr, false, true); 
    } 
    return cache; 
} 

शायद थोड़ा और कोड तो आप उम्मीद है, लेकिन optimalisation और प्रदर्शन मुक्त करने के लिए नहीं आती है।

+0

मैं इस लुकअप तंत्र से चिंतित हूं। हालांकि, मैं उलझन में हूं कि आप केवल प्रत्येक पत्र को क्यों सटीक करते हैं? क्या यह विधि पूरे शब्दों को भी कैश करती है? मान लें कि आप 20,000 तारों की सरणी में 'बल्ले' खोजना चाहते हैं। – mesqueeb

1

मैं समस्या को पुन: उत्पन्न नहीं कर सकता, मैंने एक निष्पक्ष कार्यान्वयन बनाया है, और अधिकांश ब्राउज़र 10000 15 चार तारों में मिलीसेकंड की एक अंक संख्या में खोज करते हैं। मैं आईई 6 में परीक्षण नहीं कर सकता, लेकिन मैं इसे सबसे तेज़ ब्राउज़र से 100 गुना धीमा नहीं मानूंगा, जो अभी भी लगभग तुरंत होगा। (यह है कि सिर्फ वहाँ है ध्यान दें कि निर्माण के समय इस मुद्दे से संबंधित नहीं है पर काम करने के लिए कुछ डेटा प्राप्त करने के लिए।) http://ebusiness.hopto.org/test/stacktest8.htm

एक बात आप गलत सब रेंडर करने के लिए कोशिश कर रहा है कर सकता है:

यह अपने आप का प्रयास करें नतीजे, यह काफी बड़ा काम होगा जब उपयोगकर्ता ने केवल एक ही पत्र, या एक आम अक्षर संयोजन में प्रवेश किया है।

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