2015-06-24 37 views
5

मैं कुछ जावा 8 स्ट्रीम एपीआई कोड का परीक्षण कर रहा था, लेकिन मैं यह नहीं समझ सकता कि इस के साथ क्या हो रहा है।जावा 8 अजीब व्यवहार स्ट्रीम करता है

मैं समांतरस्ट्रीम के बारे में सोच रहा था और यह कैसे काम करता है और मैंने कुछ तुलना की है। दो अलग-अलग विधियां जो 32.768.000 बिगडेसिमल जोड़ती हैं, एक समानांतरस्ट्रीम का उपयोग करते हुए, अन्य सामान्य पुनरावृत्ति का उपयोग करते हुए। मैं एक परीक्षण के साथ आया था कि मुझे पता है कि यह अमान्य है, लेकिन कुछ चीजें मेरा ध्यान बुलाती हैं।

परीक्षण कर रहे हैं:

समानांतर धारा:

private static void sumWithParallelStream() { 
    BigDecimal[] list = new BigDecimal[32_768_000]; 
    BigDecimal total = BigDecimal.ZERO; 
    for (int i = 0; i < 32_768_000; i++) { 
     list[i] = new BigDecimal(i); 
    } 
    total = Arrays.asList(list).parallelStream().reduce(BigDecimal.ZERO, BigDecimal::add); 
    System.out.println("Total: " + total); 
} 

सामान्य कोड:

private static void sequenceSum() { 
    BigDecimal total = BigDecimal.ZERO; 
    for (int i = 0; i < 32_768_000; i++) { 
     total = total.add(new BigDecimal(i)); 
    } 
    System.out.println("Total: " + total); 
} 

आउटपुट है:

Total: 536870895616000 
sumWithParallelStream(): 30502 ms 

Total: 536870895616000 
sequenceSum(): 271 ms 

तब मैं parallelStream को दूर करने की कोशिश की:

private static void sumWithParallelStream() { 
    BigDecimal[] list = new BigDecimal[32_768_000]; 
    BigDecimal total = BigDecimal.ZERO; 
    for (int i = 0; i < 32_768_000; i++) { 
     list[i] = new BigDecimal(i); 
     total = total.add(list[i]); 
    } 
    System.out.println("Total: " + total); 
} 

देखें कि sequenceSum() विधि एक ही

नई उत्पादन होता है:,

Total: 536870895616000 
sumWithParallelStream(): 13487 ms 

Total: 536870895616000 
sequenceSum(): 879 ms 

मैं ये बदलाव कर लें जोड़ने और parallelStream विधि कई बार और हटाने sequenceSum() के परिणाम कभी भी नहीं बदलते हैं, हमेशा 200 के बारे में कुछ अन्य विधि पर parallelStream का उपयोग करते समय, और उपयोग नहीं करते समय 800 के बारे में कुछ। विंडोज और उबंटू में परीक्षण।

अंत में, मेरे लिए दो प्रश्न बने रहे हैं, दूसरी विधि पर parallelStream का उपयोग क्यों किया जाता है? सरणी पर BigDecimals को संग्रहीत करने से पहली विधि बहुत धीमी हो गई (800 ms से 13000 ms)?

+1

अन्य क्रम में विधियों को कॉल करने का प्रयास करें। पहला 'अनुक्रमसम() 'और फिर' sumWithParallelStream() '। – Kayaman

+0

आप दो बहुत अलग चीजें करते हैं। जब आप समांतर विधि का उपयोग करते हैं तो आपकी पूरी सूची में अतिरिक्त पुनरावृत्ति होती है। बेशक इसमें अधिक समय लगता है। – Nitram

+4

@ निट्राम मुझे विश्वास है कि वह पूछ रहा था कि क्यों अन्य विधि 'अनुक्रमसम() 'के रनटाइम को प्रभावित करती है। जिसके लिए मैं "जेआईटी शायद" कहूंगा। – Kayaman

उत्तर

0

@apangin द्वारा टिप्पणियों की ओर इशारा करते हुए, यह मुद्दा जीसी के साथ है।

मैंने जीसी के निष्पादन समय को मुद्रित करने के लिए -XX: + प्रिंट GCDetails पैरामीटर का उपयोग किया और parallelStream के साथ वे सबसे खराब थे, शायद स्ट्रीम्स एपीआई के इनइलाइलाइजेशन को और मेमोरी आवंटित की गई थी।

3

पहले उदाहरण में आप 32,768,000 तत्वों की सरणी आवंटित कर रहे हैं और फिर स्ट्रीमिंग कर रहे हैं। उस सरणी आवंटन और स्मृति लाने की आवश्यकता नहीं है और संभवतः विधि को धीमा कर रहा है।

IntStream.range(0, limit).parallel() 
    .mapToObj(BigDecimal::new) 
    .reduce(BigDecimal.ZERO, BigDecimal::add); 
+0

वाह ... विश्वास नहीं कर सकता कि मैं थोड़ी देर के लिए जावा 8 में कोडिंग कर रहा हूं और पूरी तरह से उस समारोह को याद किया, धन्यवाद। – dolan

+0

क्षमा करें, यहां जवाब टिप्पणी पर है, मैं एक उत्तर लिखूंगा। –

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