2015-12-05 5 views
5

मैं निम्नलिखित कोड है कि जावा स्ट्रीम एपीआई के माध्यम से जा रहा द्वारा एक समानांतर फैशन में एक सूची से एक मानचित्र को भरने के लिए प्रयास करता है:मुझे कैसे पता चलेगा कि जावा स्ट्रीम संग्रह (collect.toMap) समानांतर है या नहीं?

class NameId {...} 

public class TestStream 
{ 
    static public void main(String[] args) 
    { 
     List<NameId > niList = new ArrayList<>(); 
     niList.add(new NameId ("Alice", "123456")); 
     niList.add(new NameId ("Bob", "223456")); 
     niList.add(new NameId ("Carl", "323456")); 

     Stream<NameId> niStream = niList.parallelStream(); 
     Map<String, String> niMap = niStream.collect(Collectors.toMap(NameId::getName, NameId::getId)); 
    } 
} 

मैं कैसे करूँ पता है कि नक्शे में एक से अधिक थ्रेड यानी उपयोग करते हुए, से भर जाता है समानांतर? क्या मुझे collect.toMap के बजाय collect.toConcurrentMap को कॉल करने की आवश्यकता है? क्या यह मानचित्र की आबादी को समानांतर करने का एक उचित तरीका है? मुझे कैसे पता चलेगा कि ठोस नक्शा नया niMap का समर्थन कर रहा है (उदाहरण के लिए हैश मैप)?

+0

n कोर की संख्या आपके प्रोसेसर जा रहा है:

ध्यान दें कि मेरी StreamEx पुस्तकालय जो मानक स्ट्रीम एपीआई को बढ़ाता है एक toMap() विधि है जो समानांतर धारा और अनुक्रमिक एक के लिए गैर समवर्ती संग्रह के लिए समवर्ती संग्रह का उपयोग करता है कहते हैं , आपकी समांतर धारा पर काम करने के लिए एन -1 धागा बनाया जाएगा। आपकी सूची में 3 पंक्तियां हैं, इसलिए आप अधिकतर प्रदर्शन को कम कर देंगे। –

+0

स्ट्रीम फ्रेमवर्क जानबूझकर आपके द्वारा कार्यान्वयन (समानांतर या नहीं) को छुपाता है। अगर सब ठीक से किया जाता है, तो बताने का कोई तरीका नहीं होगा। –

उत्तर

2

Javadoc से:

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

तो ऐसा लगता है जैसे toConcurrentMap आवेषण समानांतर करेगा।

बैकिंग मानचित्र डिफ़ॉल्ट रूप से HashMap है। यह सिर्फ toMap का संस्करण कहता है जो Supplier<M> लेता है और HashMap::new पास करता है। (स्रोत: स्रोत)

2

मुझे कैसे पता चलेगा कि मानचित्र एकाधिक धागे का उपयोग करके पॉप्युलेट किया गया है, यानी समानांतर में?

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

क्या मुझे संग्राहक.टैप के बजाय संग्राहक.तोConcurrentMap को कॉल करने की आवश्यकता है?

इससे समानांतर और अधिक कुशल बनाने में मदद मिलेगी, थोड़ा कम अक्षम होगा।

क्या यह मानचित्र की आबादी को समानांतर करने का एक उचित तरीका है?

तुम कर सकते हो सुझाव के रूप में हालांकि आप नोट करना चाहिए कि कहीं अधिक सब कुछ तो भी एक धागा एक बहुत यह धीमी हो जाएगी जोड़ने तुम यहाँ क्या कर रहे हैं की तुलना में महंगा है एक नया धागा शुरू करने की लागत।

मुझे कैसे पता चलेगा कि ठोस नक्शा नया niMap का समर्थन कर रहा है (उदाहरण के लिए हैश मैप)?

प्रलेखन कहता है कि आप निश्चित रूप से नहीं जान सकते हैं। पिछली बार जब मैंने toMap चेक किया था तो हैश मैप और groupingBy का उपयोग लिंकड हैशैप का उपयोग कर रहा था लेकिन आप यह नहीं मान सकते कि यह कोई विशेष मानचित्र है।

+0

niMap.getClass आपको नहीं बताएगा कि कौन सा मानचित्र उपयोग किया जाता है? –

+1

@ जीन-फ्रैंकोइससावर्ड हां, लेकिन यह जावा के सिद्धांतों या सिद्धांत के बीच एक अलग कार्यान्वयन हो सकता है कि आप इसे कैसे कहते हैं। यानी यदि आप कोई ऑब्जेक्ट खाली नहीं करते हैं तो एक खाली मैप(), या एक यह सिंगलटन मैप हो सकता है() आप इसे म्यूटेबल भी नहीं मान सकते हैं। –

+0

जब 'groupingBy' ने LinkedHashMap का उपयोग किया था? मैंने कभी यह नहीं देखा। –

1

आप अनुक्रमिक धारा के लिए toConcurrentMap और समानांतर स्ट्रीम के लिए toMap दोनों का उपयोग कर सकते हैं।अंतर

  • toConcurrentMap()
  • toMap() समानांतर धारा

के लिए की तुलना में अनुक्रमिक स्ट्रीम के लिए आम तौर पर तेजी से होता है, तो आप नहीं जानते कि जहां अपनी स्ट्रीम आया आमतौर पर तेजी से अनुक्रमिक स्ट्रीम के लिए की तुलना में समानांतर धारा के लिए है से और दोनों मामलों में इसे तेजी से बनाना चाहते हैं, आप इस तरह लिख सकते हैं:

Map<String, String> niMap = niStream.collect(
    niStream.isParallel() ? 
     Collectors.toConcurrentMap(NameId::getName, NameId::getId) : 
     Collectors.toMap(NameId::getName, NameId::getId) 
); 

अंतर है toConcurrentMap() एक CONCURRENT कलेक्टर जिसका अर्थ है कि समवर्ती डेटा संरचना प्रयोग किया जाता है (ConcurrentHashMap वर्तमान कार्यान्वयन में) जो अलग धागे से एक साथ से भरा जा सकता है। अनुक्रमिक धारा के लिए यह कुछ अनावश्यक भूमि के ऊपर लेता है, लेकिन समानांतर धारा के लिए यह toMap() मामले अलग गैर समवर्ती मानचित्र उदाहरणों हर समानांतर थ्रेड के लिए बनाया जाएगा के रूप toMap() का उपयोग करने से, तो इन मैप्स एक साथ विलय कर रहे हैं तेजी से जो बड़े नक्शे के लिए बहुत तेजी से नहीं है ।

Map<String, String> niMap = StreamEx.of(niStream) 
         .toMap(NameId::getName, NameId::getId); 
संबंधित मुद्दे