2010-02-03 3 views
7

मैं एंड्रॉइड के लिए ऐप बना रहा हूं, मेरी गतिविधि में मुझे लगभग 10000 तारों की एक सरणी लोड करने की आवश्यकता है। डेटाबेस से इसे लोड करना धीमा था, इसलिए मैंने इसे सीधे एक .java फ़ाइल (एक निजी क्षेत्र के रूप में) में डालने का फैसला किया। मेरे पास स्ट्रिंग एरे युक्त इन कक्षाओं में से लगभग 20 हैं और मेरा प्रश्न यह है कि, मेरे आवेदन शुरू होने के बाद स्मृति में लोड की गई सभी कक्षाएं हैं? यदि ऐसा है तो जिस गतिविधि में मुझे इन तारों की आवश्यकता है, उसे जल्दी से लोड किया जाएगा, लेकिन पूरी तरह से एप्लिकेशन की धीमी शुरुआत होगी ... क्या कोई अन्य तरीका है, फ़ाइल से 10000 स्ट्रिंग सरणी को कितनी जल्दी लोड करना है?क्या एप्लाइक्शन शुरू होने के बाद मेरे जावा एप्लिकेशन में सभी .class फ़ाइलें स्मृति में लोड हो गई हैं?

अद्यतन: मुझे इन तारों की आवश्यकता क्यों है? मेरा एंड्रॉइड ऐप आपको प्राग के सार्वजनिक पारगमन में "यात्रा" ढूंढने की अनुमति देता है - आप प्रस्थान स्टॉप, आगमन स्टॉप चुनते हैं और यह आपकी यात्रा पाता है (here देखें)। मेरे ऐप में एक सुझाव सुविधा है - आप अपने प्रस्थान स्टॉप के रूप में लीटर "सी" दर्ज करते हैं और एक सुझाव ListView "c" से शुरू होने वाली स्टॉप के साथ प्रकट होता है। इन सुझावों के लिए मुझे तारों की आवश्यकता है। डेटाबेस से सुझाव प्राप्त करना धीमा है (जी 1 पर लगभग 400 मिमी)।

+0

उन तारों के लिए क्या हैं? – Macarse

+0

अधिकतर एंड्रॉइड डिवाइस मुख्य मेमोरी से भूखे हैं, यदि संभव हो तो मैं उन स्ट्रिंग्स को फ्लाई पर उत्पन्न करूंगा। –

+0

यदि आप उन्हें किसी सूची में दिखा रहे हैं, तो ListView + CursorAdapter उन्हें फ्लाई पर बहुत तेज़ी से लोड करेगा। ऐसे बुनियादी मामले के लिए आपको Android पर SQLite के साथ कोई प्रदर्शन समस्या नहीं होनी चाहिए। –

उत्तर

4

पहला, एक साधारण डेटाबेस क्वेरी करने के लिए 400ms वास्तव में धीमा है। इतना धीमा है कि मुझे संदेह होगा कि आपके डेटाबेस स्कीमा (उदा। इंडेक्स) या आपके डेटाबेस कनेक्शन कॉन्फ़िगरेशन में कुछ समस्या है।

लेकिन अगर आप एक गंभीर एक डेटाबेस का उपयोग नहीं के बारे में, वहाँ आप वर्तमान में क्या कर रहे हैं के लिए विकल्प के एक जोड़े हैं:

  1. , व्यवस्था है कि सरणियों युक्त वर्गों lazily के रूप में आवश्यक लोड किए गए हैं Class.forName(...) का उपयोग कर । यदि आप इसे सही तरीके से कार्यान्वित करते हैं, तो कचरा कलेक्टर के लिए कक्षाओं को पुनः प्राप्त करने के बाद इसे पुनः प्राप्त करना संभव होना चाहिए और तारों को आपकी प्राथमिक डेटा संरचना में जोड़ा गया है।

  2. 10000 स्ट्रिंग्स को एक सपाट फ़ाइल में बदलें, फ़ाइल को अपने ऐप की JAR फ़ाइल में डाल दें। फिर फ़ाइल खोलने के लिए Class.getResourceAsStream(...) का उपयोग करें और इसे इन-मेमोरी सरणी में पढ़ें।

  3. उपरोक्त के रूप में, लेकिन एक अनुक्रमित फ़ाइल का उपयोग करके और सरणी को डेटा संरचना के साथ बदलना जो आपको फ़ाइल से स्ट्रिंग्स को आलसी पढ़ने की अनुमति देता है। (यह थोड़ा जटिल होगा, लेकिन यदि आप 10000 स्ट्रिंग्स द्वारा उपभोग की गई स्मृति से चिंतित हैं, तो इससे पता चलता है।)

+0

धन्यवाद, अब मैं कक्षा का उपयोग कर रहा हूं .forName ("") और यह बहुत तेज़ है। – fhucho

3

एक कक्षा केवल तभी लोड की जाती है जब इसे पहले संदर्भित किया जाता है।

हालांकि आपको 10000 की सरणी की आवश्यकता है, तो आपको एक बार में सभी की आवश्यकता नहीं हो सकती है। यहां वह जगह है जहां पेजिंग की अवधारणा आती है। यह लिंक इंगित करता है कि Paging is often done in Android। आरंभ में स्मृति में केवल थोड़ी सी सरणी है, और जैसा कि आपको इसकी आवश्यकता है, इसे स्मृति में लोड करना जारी रखें और अगर इच्छित नहीं हो तो स्मृति से किसी भी पिछले डेटा को उतारना जारी रखें।

उदा। किसी भी तालिका में, एक शॉट पर, उपयोगकर्ता 50 सर्वश्रेष्ठ रिकॉर्ड देख सकता है, फिर उसे स्क्रॉल करना होगा (उसकी स्क्रीन पर विचार करना iMax movie theatre का आकार नहीं है)। जब वह स्क्रॉल करता है, तो डेटा के अगले हिस्से को लोड करें और किसी भी डेटा को अनलोड करें जो अब उपयोगकर्ता के लिए अविभाज्य है।

+0

दुर्भाग्य से मुझे सभी 10000 की आवश्यकता है (अद्यतन प्रश्न देखें)। तो अगर मेरे पास अपने गतिविधि कोड में कक्षा का नाम कहीं है, तो मेरी गतिविधि शुरू होने पर जेवीएम वर्ग लोड करेगा? – fhucho

+0

@fhucho - हाँ यह होगा। –

+0

एंड्रॉइड के बारे में निश्चित नहीं है लेकिन सूर्य जेवीएम आलसी लोडिंग करता है। पहली बार उपयोग किए जाने पर कक्षा शुरू की जाएगी। उदाहरण के लिए पहली बार कुछ कोड कक्षा से स्थिर मूल्य का उपयोग करते हैं या उस पर नए कॉल करते हैं। बस इसे आयात करना कुछ भी नहीं करता है और यदि आपके निष्पादन पथ में नया या MyClass.staticMethod() नहीं कहा जाता है तो यह कभी लोड नहीं होता है। –

1

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

http://www.developer.com/java/other/article.php/2248831/Java-Class-Loading-The-Basics.htm

0

से मुझे नहीं लगता कि आप 10K स्ट्रिंग्स, जावा फ़ाइलों में hardcoded को बनाए रखने के साथ खुश हो जाएगा है।

बल्कि जांचें कि क्या आप अपनी समस्या के लिए सही डेटाबेस का उपयोग कर रहे हैं और यदि आपके सूचकांक सही तरीके से सेट हैं। एक गलत सूचकांक वास्तव में खराब प्रदर्शन कर सकता है।

इसके अतिरिक्त आपको क्वेरी द्वारा दिए गए परिणामों की मात्रा सीमित करनी चाहिए, लेकिन सुनिश्चित करें कि आप प्रविष्टियों को एक-एक करके नहीं लाते हैं।

यदि कुछ भी फिट बैठता है, तो भी आप स्टार्टअप पर डेटाबेस से स्ट्रिंग को प्रीलोड कर सकते हैं।

आप प्रीलोड कर सकते हैं, चलो प्रत्येक अक्षर के लिए 10 प्रविष्टियां कहें। यदि किसी चरित्र में कुंजी है, तो आप उस चरित्र के साथ प्रविष्टियों को दूसरे के बाद प्रीलोड कर सकते हैं और इसी तरह।

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