2011-12-21 9 views
20

जावा विशेषज्ञ समयपूर्व अनुकूलन से बचने के महत्व, और स्वच्छ ओओ डिजाइन पर ध्यान केंद्रित करने के महत्व पर जोर देते हैं। मैं इस सिद्धांत को दोबारा लिखने के संदर्भ में इस सिद्धांत को सुलझाने की कोशिश कर रहा हूं जो लंबे तत्वों (कुछ मिलियन) की एक बड़ी श्रृंखला का उपयोग करता है। ऐसा लगता है कि एक ऐरेलिस्ट का उपयोग करने से लगभग 3x लंबे समय तक एक प्राचीन सरणी की स्मृति का उपभोग होगा, और यह बर्बाद कर रहा है कि बहुत सी रैम मेरे लिए एक वैध चिंता की तरह लगती है।सूची <Double> जो डबल [] की रैम का उपयोग करता है?

मैं इसे मेमोरीटेस्टबेन्च क्लास described here का उपयोग करके एक प्रयोग से दूर कर रहा हूं।

package memory; 

import java.util.ArrayList; 
import java.util.List; 

public class ArrayListExperiment { 

public static void main(String[] args) { 

    ObjectFactory arrayList = new ObjectFactory() { 
     public Object makeObject() { 
      List<Long> temp = new ArrayList<Long>(1000); 
      for (long i=0; i<1000; i++) 
       temp.add(i); 
      return temp; 
     } 
    }; 

    ObjectFactory primitiveArray = new ObjectFactory() { 
     public Object makeObject() { 
      long[] temp = new long[1000]; 
      for (int i=0; i<1000; i++) 
       temp[i] = i; 
      return temp; 
     } 
    }; 

    MemoryTestBench memoryTester = new MemoryTestBench(); 
    memoryTester.showMemoryUsage(primitiveArray); 
    memoryTester.showMemoryUsage(arrayList); 
} 
} 

और आउटपुट:

memory.ArrayListExperiment$2 produced [J which took 8016 bytes 
memory.ArrayListExperiment$1 produced java.util.ArrayList which took 24968 bytes 

मेरा प्रश्न है: मैं एक OO सूची के लाभ कैसे काटते कर सकते हैं और अभी भी एक आदिम सरणी के छोटे स्मृति पदचिह्न को बनाए रखने के अपने परीक्षण और उत्पादन इस प्रकार हैं ? मुझे लगता है कि अमरूद उत्तर प्रदान कर सकता है, लेकिन एपीआई के माध्यम से चमक रहा है यह मेरे लिए स्पष्ट नहीं है कि कौन सा वर्ग ArrayList के स्थान पर उपयोग करना है।

किसी भी सुझाव के लिए धन्यवाद।

+0

इस MemoryTestBranch सही है है? मैंने जल्द ही लेख के माध्यम से चले गए हैं और कुछ समय के लिए System.gc() एक के बाद कुछ दिलचस्प दृष्टिकोण देखा है। – rit

+4

वास्तव में, यह सही के बारे में लगता है। एक डबल एक संदर्भ लागत, साथ ही वास्तविक आदिम डबल। 64 बिट जेवीएम में कम से कम एक बार आप डबल के लिए दो गुना अधिक भुगतान करेंगे, और कुछ अतिरिक्त ओवरहेड होगा। – rfeak

+1

rit, मैं उस आलेख में विधि की सफाई पर टिप्पणी करने के लिए योग्य नहीं हूं, लेकिन मुझे विश्वास है कि स्मृति परिणाम सही हैं – Jonah

उत्तर

11

आप, Trove, जो आदिम संग्रह के लिए सहायता प्रदान करता है विचार कर सकते हैं, उदाहरण के लिए TDoubleArrayList वर्ग:

एक आकार बदलने योग्य, डबल पुरातन की सरणी समर्थित सूची।

संपादित करें: ऐसा नहीं है कि इस वर्ग के List को लागू नहीं करता है सच है, लेकिन यह है कि बॉक्स्ड पुरातन से बचने के जावा के मूल्य है। Guava's solution सबसे बहुमुखी है, जबकि ट्रोव अधिक चरम प्रदर्शन आवश्यकताओं के लिए सबसे अच्छा है।

+1

ट्रोव जीतने का तरीका निश्चित रूप से है। रैम का उपयोग अमरूद के समान ही है, लेकिन ट्रोव की मेमोरी एक्सेस प्राइमेटिव्स के समान दो गुना है: http://pastebin.com/Xyd6MbEq – Jonah

+3

...दूसरी तरफ यह 'सूची' इंटरफ़ेस को लागू नहीं करता है;) – Xaerxess

3

एरेलेलिस्ट का अपना कार्यान्वयन लिखें जो प्राइमेटिव्स की एक सरणी का उपयोग करता है। वर्तमान ArrayList कोड की प्रतिलिपि बनाएँ और आंतरिक ऑब्जेक्ट [] को डबल [] से प्रतिस्थापित करें।

एक बहुत सीधी प्रतिलिपि प्रतिलिपि और प्रतिस्थापित होना चाहिए।

संपादित करें: स्मृति खपत के लिए सबसे बड़ा खतरा "बढ़ने" के लिए जा रहा है। यह संक्षेप में कम से कम दो बार अंतरिक्ष ले जाएगा, साथ ही अतिरिक्त कमरा जो आप बढ़ते हैं। यदि आप इससे बचने के लिए सरणी को पूर्व-आकार नहीं दे सकते हैं, तो आप थोड़ा अलग कार्यान्वयन पर विचार करना चाहेंगे जो कई एरे का उपयोग करता है क्योंकि यह समय के साथ बढ़ता है। डालने और अनुक्रमण पर थोड़ा और गणित, लेकिन बहुत बुरा नहीं होना चाहिए।

1

Arrays.asList(T...) जो भी आप खोज रहे हैं हो सकता है। यह List<T> का एक उदाहरण देता है जो इसे पारित सरणी द्वारा समर्थित है।

+4

वह अभी भी डबल [] बनाने के प्रारंभिक ओवरहेड का भुगतान करेगा, जिसे वह टालना चाहता है। – rfeak

+0

ध्यान रखें कि परिणामस्वरूप सूची निश्चित आकार होगी, इसलिए आप त्रुटियों के बिना 'add() 'पर कॉल नहीं कर पाएंगे। यदि आप सूची में जोड़ने में सक्षम होना चाहते हैं तो आपको मेमोरी ओवरहेड के साथ नियमित 'ऐरेलिस्ट' की आवश्यकता होगी। –

+0

जेसन, सूची का आकार निश्चित है और मेरी विशेष समस्या के लिए अग्रिम में जाना जाता है, fwiw – Jonah

5

मुझे लगता है कि आप FastUtil'sDoubleArrayList के लिए देख रहे हैं - यह एक प्राचीन सरणी द्वारा समर्थित है।

अपने संग्रह वास्तव में बड़ा (2^31 तत्वों से भी बड़ा) आप भी अपने BigArrays

1

यह एक अच्छा सवाल है को देखने के लिए चाहते हो सकता है है - प्रदर्शन बनाम कोड-सफाई। मुझे लगता है कि आपके पास स्वच्छ ओओ डिज़ाइन के बारे में कम चिंता करने के आधार हैं और बस लंबे समय तक बड़ी संख्या में काम करने की विशिष्ट समस्या का एक अच्छा समाधान बनाने पर ध्यान केंद्रित करते हैं। यदि आप ऐसा करते हैं, तो प्रदर्शन-उन्मुख कोड को एक वर्ग/पैकेज में रखते हुए समग्र डिजाइन पर इसका प्रभाव कम हो जाएगा। मान लीजिए कि लंबी अवधि की बड़ी सूची का प्रबंधन एक बड़े आवेदन का केवल एक छोटा सा हिस्सा है ...

16

मुझे लगता है कि क्या आप अमरूद में की तलाश में Doubles.asList

+1

एक गुवा डेवलपर के रूप में बोलते हुए, यह वास्तव में चीजों को करने का तरीका है, विशेष रूप से, जैसा कि आप उल्लेख करते हैं, आपकी सूची का आकार निश्चित है। –

+0

@ लुइस वासरमैन: क्या गुवा संस्करण कुछ भी प्रदान करता है जो 'Arrays.asList' नहीं करता है? –

+7

@ टिमोथी जोन्स: 'Arrays.asList' आदिम सरणी के लिए काम नहीं करता है ... एक' डबल [] 'में गुजरता है और आपको एक तत्व मिलता है' सूची '। – ColinD

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