2012-11-11 14 views
5

मैं जावा के साथ कुशलता से बड़ी सीएसवी प्रारूपित फ़ाइलों (आमतौर पर 200-600 एमबी) लोड करने की कोशिश कर रहा हूं (कम स्मृति और जितनी जल्दी संभव हो सके)। वर्तमान में, कार्यक्रम स्ट्रिंग Arrays की एक सूची का उपयोग कर रहा है। इस ऑपरेशन को पहले प्रत्येक सीएसवी पंक्ति के लिए एक टेबल का उपयोग करके एक लूआ प्रोग्राम के साथ संभाला गया था और प्रत्येक "पंक्ति" तालिका को रखने के लिए एक तालिका थी।जावा - स्ट्रिंग सरणी की बड़ी मात्रा को कुशलतापूर्वक कैसे स्टोर करें

नीचे स्मृति मतभेद और लोड समय का एक उदाहरण है:

  • CSV फ़ाइल - 232mb
  • लुआ - स्मृति में 1,378mb - - स्मृति में 549mb - 157 सेकंड
  • जावा लोड करने के लिए 12 लोड करने के लिए सेकंड

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

नीचे CSV फ़ाइलों के भीतर डेटा पर कुछ पृष्ठभूमि है:

  • प्रत्येक क्षेत्र एक स्ट्रिंग के होते हैं
  • प्रत्येक पंक्ति के भीतर विशिष्ट क्षेत्रों स्ट्रिंग्स (उदाहरण के लिए क्षेत्र का एक सेट में से एक में शामिल हो सकते 3 हो सकता है "लाल", "हरा", या "नीला")।
  • सामग्री के भीतर डुप्लिकेट स्ट्रिंग्स हैं।

नीचे क्या लोड डेटा की आवश्यकता हो सकती है के कुछ उदाहरण हैं:

  • एक दिया स्ट्रिंग के साथ मेल खाते हैं और एक जीयूआई में मिलान स्ट्रिंग्स
  • प्रदर्शन मैचों वापस जाने के लिए प्रयास करने से सभी स्ट्रिंग्स के माध्यम से खोजें टेबल (फ़ील्ड के माध्यम से सक्षम सॉर्ट करें)।
  • स्ट्रिंग्स को बदलें या बदलें।

मेरा प्रश्न - क्या कोई संग्रह है जिसके लिए डेटा को पकड़ने के लिए कम स्मृति की आवश्यकता होगी फिर भी डेटा को आसानी से और जल्दी से खोज/सॉर्ट करने के लिए अभी भी सुविधाएं प्रदान करें?

+1

अगर आपको लगता है कि कॉलम 3 पता केवल कुछ संभावित मान रखती है, आप कर सकते थे [प्रशिक्षु उन्हें] (http://docs.oracle मेमोरी उपयोग को कम करने के लिए .com/javase/7/docs/api/java/lang/String.html # intern% 28% 29)। यह भी देखें: http://stackoverflow.com/a/1855195/829571 – assylias

+0

धन्यवाद assylias मैं इसका उपयोग करके कुछ परीक्षण चलाऊंगा। क्या आप जानते हैं कि यह छोटे स्ट्रिंग्स के लिए कुशल है - उदा। "टू" या "गो"। अधिकांश क्षेत्रों में तार होते हैं जो 45 वर्ण + होते हैं, हालांकि, कुछ काफी कम (4 या उससे कम) होते हैं। – user1816198

+2

http://stackoverflow.com/questions/12792942/alternatives-to-java-string-interning –

उत्तर

0

हो सकता है कि इस लेख में कुछ मदद की हो सकती है:

http://www.javamex.com/tutorials/memory/string_saving_memory.shtml

+0

धन्यवाद - बहुत उपयोगी जानकारी। – user1816198

+1

मैंने लेख के माध्यम से प्रस्तुत दोनों उदाहरणों को आजमाया। यह इंटर्न() सबसे अधिक स्मृति बचाता है। मैं प्रयोग करना जारी रखूंगा (विशेष रूप से जब मैं अपने प्रोजेक्ट को खत्म कर दूंगा) लेकिन यह निश्चित रूप से लूआ के साथ मेरी मेमोरी उपयोग को बहुत तेज लोड समय के साथ रखता है। – user1816198

+0

यही कारण है कि आपको केवल लिंक ही नहीं करना चाहिए - लिंक अब मर चुका है। –

0

अपनी मेमोरी समस्या को अनुकूलित करने के लिए मैं Flyweight पैटर्न का उपयोग करने की सलाह देता हूं, खासकर ऐसे क्षेत्रों के लिए जिनके पास बहुत सारे डुप्लिकेट हैं।

संग्रह के रूप में आप TreeSet या TreeMap का उपयोग कर सकते हैं।

आप अपने LineItem वर्ग के लिए एक अच्छा कार्यान्वयन देते हैं (लागू equals, hashcode और Comparable) आप स्मृति एक बहुत का उपयोग का अनुकूलन कर सकते हैं।

0

DAWG

एक निर्देशित अचक्रीय शब्द ग्राफ शब्द को स्टोर करने के लिए सबसे कारगर तरीका (स्मृति की खपत के लिए सबसे अच्छा वैसे भी) है।

लेकिन संभवतः यहां पर अधिक वृद्धि हुई है, क्योंकि अन्य ने कहा है कि डुप्लीकेट नहीं बनाते हैं, वही उदाहरण के लिए कई संदर्भ बनाते हैं।

+0

धन्यवाद मैं इस विकल्प को और अधिक देखूंगा। मैं अभी तक कुछ भी ज्यादा नहीं मानूंगा - जितना अधिक कुशल होगा उतना अधिक डेटा प्रति सत्र लोड किया जा सकता है और यह अंतिम उपयोगकर्ता के लिए बेहतर है। – user1816198

0
सिर्फ एक पक्ष नोट के रूप में

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

इतना यकीन नहीं कैसे lua काम करता है, लेकिन जावा में यह भी

+0

लेकिन यदि यह बराबर है तो यह अनावश्यक है और == तुलनात्मकता – Igor

+0

तुलना के लिए काम करेगा, बराबर सही तरीका है, क्योंकि जिस तरह से आपको जावा में वस्तुओं की तुलना करना चाहिए, == भी काम करेगा, लेकिन यह केवल दयालु है साइड इफेक्ट के कारण, जेवीएम आंतरिक रूप से तारों को संभालता है –

+0

खैर, मुझे यकीन नहीं है कि स्ट्रिंग संदर्भों को रखने के लिए आंतरिक रूप से कितनी मेमोरी जावा वीएम रखती है, लेकिन मुझे पूरा यकीन है कि पर्याप्त बड़े कार्यक्रम में == – Igor

1

एक आसान उपाय काफी कुशल होना चाहिए। आप कुछ HashMap प्राप्त कर सकते हैं क्या आप सभी अद्वितीय तारों के संदर्भ डाल देंगे। और ArrayList में आपके पास HashMap में मौजूदा अद्वितीय तारों का संदर्भ होगा।

कुछ की तरह:

private HashMap<String, String> hashMap = new HashMap<String, String>(); 

public String getUniqueString(String ns) { 
    String oldValue = hashMap.get(ns); 
    if (oldValue != null) { //I suppose there will be no null strings inside csv 
    return oldValue; 
    }   
    hashMap.put(ns, ns); 
    return ns; 
} 

सरल उपयोग:

List<String> s = Arrays.asList("Pera", "Zdera", "Pera", "Kobac", "Pera", "Zdera", "rus"); 
List<String> finS = new ArrayList<String>(); 
for (String er : s) { 
    String ns = a.getUniqueString(er); 
    finS.add(ns); 
} 
+0

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

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