2012-03-29 24 views
7

मेरी जावा कोड, मैं अमरूद के मल्टीमैप (com.google.common.collect.Multimap) का उपयोग कर रहा में इस का उपयोग करते हुए:मल्टीमैप अंतरिक्ष मुद्दा: अमरूद

Multimap<Integer, Integer> Index = HashMultimap.create() 

यहाँ, मल्टीमैप कुंजी एक यूआरएल के कुछ हिस्से और मूल्य यूआरएल के एक अन्य भाग है (एक पूर्णांक में परिवर्तित)। अब, मैं अपना जेवीएम 2560 एमबी (2.5 जीबी) हीप स्पेस (एक्सएमएक्स और एक्सएमएस का उपयोग करके) असाइन करता हूं। हालांकि, यह केवल पूर्णांक के 9 लाख (कुंजी, मूल्य) जोड़े (लगभग 10 मिलियन) स्टोर कर सकता है। लेकिन, सैद्धांतिक रूप से (स्मृति के अनुसार int पर कब्जा कर लिया गया) इसे और अधिक स्टोर करना चाहिए।

किसी को भी मेरी मदद कर सकते,

  1. क्यों Multimap स्मृति के बहुत सारे उपयोग कर रहा है? मैंने अपना कोड चेक किया और जोड़े को Multimap में डाले बिना, यह केवल 1/2 एमबी मेमोरी का उपयोग करता है।
  2. 2.

वहाँ एक और तरीका है या घर में पके हुए समाधान इस स्मृति मुद्दे को हल करने के लिए है? मतलब, क्या उन ऑब्जेक्ट ओवरहेड्स को कम करने का कोई तरीका है क्योंकि मैं केवल इंट-इंट स्टोर करना चाहता हूं? किसी अन्य भाषा में? या किसी भी अन्य समाधान (घर-बेक्ड पसंदीदा) को हल करने के लिए मुझे सामना करने के लिए, डीबी आधारित या उस समाधान की तरह कुछ मतलब है।

+4

क्या आपने "सैद्धांतिक" आकार को काम करते समय ऑब्जेक्ट ओवरहेड खाते में लिया था? आप इंटीजर का उपयोग कर रहे हैं, int नहीं ... –

+0

@ जोन्स स्केट, मैं वास्तव में माफी चाहता हूँ। धन्यवाद। – Arpssss

+0

कोई समस्या नहीं - और निश्चित रूप से आप * जावा में जेनेरिक प्रकार तर्क के रूप में * int' का उपयोग नहीं कर सकते हैं। आप शायद ओवरहेड से बचने के लिए int multapap को समर्पित int चाहते हैं :( –

उत्तर

9

Multimap से जुड़ी भारी मात्रा में ओवरहेड है। कम से कम:

  • प्रत्येक कुंजी और मान एक Integer वस्तु है, जो (कम से कम) प्रत्येक int मूल्य का भंडारण आवश्यकताओं दोगुना हो जाता है है।
  • HashMultimap में प्रत्येक अद्वितीय कुंजी मान मूल्यों की एक Collection साथ जुड़ा हुआ है (the source के अनुसार, Collection एक Hashset है)।
  • प्रत्येक Hashset 8 मानों के लिए डिफ़ॉल्ट स्थान के साथ बनाया गया है।

इसलिए प्रत्येक कुंजी/मूल्य जोड़ी की आवश्यकता होती है (कम से कम) शायदमानों के मुकाबले अधिक जगह की परिमाण की आवश्यकता हो सकती है। (कुछ हद तक कम जब एक ही कुंजी के तहत एकाधिक मान संग्रहीत किए जाते हैं।) मैं उम्मीद करता हूं कि 10 मिलियन कुंजी/मूल्य जोड़े शायद 400 एमबी लेंगे।

हालांकि आपके पास 2.5 जीबी ढेर की जगह है, लेकिन यह सब आश्चर्यचकित नहीं होगा अगर यह पर्याप्त नहीं है। उपरोक्त अनुमान, मुझे लगता है, कम तरफ। इसके अलावा, यह केवल खाते के निर्माण के बाद मानचित्र को स्टोर करने के लिए कितना आवश्यक है। जैसे-जैसे नक्शा बढ़ता है, तालिका को फिर से आवंटित करने और पुनर्स्थापित करने की आवश्यकता होती है, जो अस्थायी रूप से कम से कम स्थान की मात्रा को दोगुना कर देता है। अंत में, यह सब मानता है कि int मान और ऑब्जेक्ट संदर्भों को 4 बाइट की आवश्यकता होती है। यदि JVM 64-बिट एड्रेसिंग का उपयोग कर रहा है, तो बाइट गिनती शायद दोगुनी हो सकती है।

+0

धन्यवाद। मुझे मिल गया। लेकिन क्या ऊपर सूचीबद्ध ओवरहेड्स को कम करने का कोई तरीका है क्योंकि मैं केवल इंट-इंट स्टोर करना चाहता हूं? किसी भी अन्य भाषा में ? या किसी भी अन्य समाधान (घर-बेक्ड पसंदीदा) को हल करने के लिए मुझे सामना करना पड़ता है जिसका अर्थ है डीबी आधारित या उस समाधान की तरह कुछ। – Arpssss

+0

@Arpssss [एनआईएसटी द्वारा बनाए गए इस सूची] (जावा numerics पुस्तकालयों के http://math.nist.gov/javanumerics/) है। उनमें से कई आदिम संग्रह का समर्थन करते हैं, लेकिन मुझे मल्टीमैप्स का समर्थन करने वाले किसी भी व्यक्ति के बारे में पता नहीं है। कुछ अध्ययनों के अनुसार (उदाहरण के लिए, [यह एक] (http://b010.blogspot.com/2009/05/speed-comparison-of-1-javas-built-in.html)), ये पुस्तकालय बहुत तेज हैं, लेकिन इतना अधिक जगह नहीं बचाओ। [इस धागे] पर एक नज़र डालें (http://stackoverflow.com/questions/3307622/java-primitive-collections-library)। –

+0

एफवाईआई, मैं गुवा टीम पर हूं और बड़ी स्मृति मेमोरी को कम करने के लिए दीर्घकालिक परियोजना पर काम कर रहा हूं। 'HashMultimap'। तो यह भविष्य में सुधार होगा। उस ने कहा, 'हैशसेट' के पास _huge_ मेमोरी ओवरहेड है। –

1

ऐसा लगता है कि आपको एक स्पैस बूलियन मैट्रिक्स की आवश्यकता है। Sparse matrices/arrays in Java लाइब्रेरी कोड को पॉइंटर्स प्रदान करना चाहिए। फिर मल्टीमैप में (i, j) डालने के बजाय, बस [1] [j] पर मैट्रिक्स में 1 डाल दें।

+0

येश। इस योजना के साथ, किसी दिए गए कुंजी के लिए सभी मान वापस करना महंगा होगा। आपको एक संपूर्ण मैट्रिक्स पंक्ति को स्कैन करना होगा और कॉलम के सूचकांक को 1. –

+2

@TedHopp, no।यह एक घने मैट्रिक्स में सच है लेकिन एक स्पैर मैट्रिक्स में नहीं है। एक अच्छी स्पैस मैट्रिक्स कक्षा में गैर-शून्य कोशिकाओं को गिनने का एक तरीका होना चाहिए। संक्षेप में आप ['nonzero'] (http://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.lil_matrix.nonzero.html#scipy-sparse-lil-matrix-nonzero) का उपयोग करते हैं । –

+0

सिद्धांत सिद्धांत में लिया गया - मूल्य प्राप्त करने के लिए शायद एक स्पैर मैट्रिक्स के पंक्ति स्लाइस दृश्य का उपयोग करने का एक तरीका है। फिर 'nonzero' जैसे कुछ मूल्यों की वांछित सूची पुनर्प्राप्त कर सकते हैं। हालांकि, जावा लाइब्रेरी जो मुझे पता है, उनके पास 'nonzero' के अनुरूप नहीं हैं। –

4
शायद

स्मृति भूमि के ऊपर कम करने के लिए संभावित Trove's आदिम संग्रह कार्यान्वयन (मुक्केबाजी के स्मृति भूमि के ऊपर से बचने के लिए) मिश्रण और

SetMultimap<Integer, Integer> multimap = Multimaps.newSetMultimap(
    TDecorators.wrap(TIntObjectHashMap<Collection<Integer>>()), 
    new Supplier<Set<Integer>>() { 
    public Set<Integer> get() { 
     return TDecorators.wrap(new TIntHashSet()); 
    } 
    }); 

अभी भी मुक्केबाजी के उपरि है यही कारण है कि जैसे अमरूद के Multimap, कुछ करने के लिए किया जाएगा सबसे आसान तरीका और प्रश्नों पर अनबॉक्सिंग, लेकिन वहां बस बैठे मेमोरी में काफी कमी आएगी।

+0

हल करने का अच्छा तरीका। हालांकि, क्या यह प्रदर्शन समस्या नहीं बना रहा है? – Arpssss

+0

इसे किसी सामान्य 'मल्टीमैप' के साथ अनुभव करने से अधिक प्रदर्शन समस्या नहीं बननी चाहिए, और इसमें आपके प्रस्तावित वैकल्पिक फ़ाइल-समर्थित समाधान की तुलना में प्रदर्शन जुर्माना के बहुत अधिक शामिल होंगे। ट्रोव के लिए –

+1

+1। ध्यान दें कि कोड को छोटा किया जा सकता है [TDecorators] (http://trove4j.sourceforge.net/javadocs/gnu/trove/TDecorators.html) स्थिर फैक्ट्री विधियों के लिए धन्यवाद। अनुमान टाइप करने के लिए धन्यवाद, 'नया TIntObjectMapDecorator <संग्रह > (नया TIntObjectHashMap <संग्रह >()) 'TDecorators.wrap बन जाता है (नया TIntObjectHashMap <संग्रह >())'। –

0

आप शायद एक ऐरेलिस्टमल्टीमैप का उपयोग कर सकते हैं, जिसके लिए हैशमल्टीमैप की तुलना में कम स्मृति की आवश्यकता होती है, क्योंकि ऐरेलिस्ट्स हैशसेट्स से छोटे होते हैं। या, आप स्मृति उपयोग को कम करने के लिए, सूची के साथ सेट को प्रतिस्थापित करने, लुइस के ट्रोव समाधान को संशोधित कर सकते हैं।

कुछ एप्लिकेशन इस तथ्य पर निर्भर करते हैं कि हैशमल्टीमैप SetMultimap इंटरफ़ेस को संतुष्ट करता है, लेकिन अधिकांश नहीं।

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