java - जावा 8 स्ट्रीम: एकाधिक फ़िल्टर बनाम जटिल स्थिति




2 Answers

कोड को दोनों विकल्पों के लिए निष्पादित किया जाना इतना समान है कि आप विश्वसनीय परिणाम की भविष्यवाणी नहीं कर सकते हैं। अंतर्निहित वस्तु संरचना भिन्न हो सकती है लेकिन हॉटस्पॉट अनुकूलक के लिए यह कोई चुनौती नहीं है। तो यह अन्य आसपास की स्थितियों पर निर्भर करता है जो किसी भी अंतर में तेजी से निष्पादन के लिए उपज करेंगे।

दो फ़िल्टर उदाहरणों का संयोजन अधिक ऑब्जेक्ट बनाता है और इसलिए अधिक प्रतिनिधि कोड बनाता है लेकिन यदि आप लैम्ब्डा अभिव्यक्तियों के बजाय विधि संदर्भों का उपयोग करते हैं, तो यह filter(x -> x.isCool()) को filter(ItemType::isCool) द्वारा filter(ItemType::isCool) । इस तरह आपने अपनी लैम्ब्डा अभिव्यक्ति के लिए बनाई गई कृत्रिम प्रतिनिधि पद्धति को समाप्त कर दिया है। तो दो विधि संदर्भों का उपयोग करके दो फ़िल्टरों को संयोजित करने से && साथ लैम्ब्डा अभिव्यक्ति का उपयोग करके एक filter आमंत्रण की तुलना में समान या कम प्रतिनिधिमंडल कोड बना सकता है।

लेकिन, जैसा कि कहा गया है, इस प्रकार का ओवरहेड हॉटस्पॉट अनुकूलक द्वारा समाप्त किया जाएगा और नगण्य है।

सिद्धांत रूप में, दो फ़िल्टरों को एक फ़िल्टर से समान समांतर किया जा सकता है लेकिन यह केवल कम्प्यूटेशनल तीव्र कार्यों के लिए प्रासंगिक है।

तो कोई आसान जवाब नहीं है।

निचली पंक्ति है, गंध पहचान सीमा के नीचे ऐसे प्रदर्शन मतभेदों के बारे में मत सोचो। अधिक पठनीय क्या है का प्रयोग करें।

¹ ... और बाद के चरणों के समांतर प्रसंस्करण करने के कार्यान्वयन की आवश्यकता होगी, वर्तमान में मानक स्ट्रीम कार्यान्वयन द्वारा नहीं लिया गया एक सड़क

कभी-कभी आप Stream को एक से अधिक शर्त के साथ फ़िल्टर करना चाहते हैं:

myList.stream().filter(x -> x.size() > 10).filter(x -> x.isCool()) ...

या आप एक जटिल स्थिति और एक filter साथ ऐसा ही कर सकते हैं:

myList.stream().filter(x -> x.size() > 10 && x -> x.isCool()) ...

मेरा अनुमान है कि दूसरे दृष्टिकोण में बेहतर प्रदर्शन विशेषताएं हैं, लेकिन मुझे यह नहीं पता है।

पहला दृष्टिकोण पठनीयता में जीतता है, लेकिन प्रदर्शन के लिए बेहतर क्या है?




एक सेट में, मेरे पास एक विशिष्ट वस्तुओं के लिए 10 हजार संदर्भ हैं। तब मैंने "स्पीड टेस्ट" किया:

long time1 = System.currentTimeMillis();    
users.stream()
     .filter((u) -> u.getGender() == Gender.FEMALE && u.getAge() % 2 == 0);
long time2 = System.currentTimeMillis();
System.out.printf("%d milli seconds", time2 - time1);

10 निष्पादन के बाद औसत समय 45,5 मिलीसेकंड था। अगला, मैं बहु फ़िल्टर () का उपयोग करता हूं:

long time1 = System.currentTimeMillis();    
users.stream()
     .filter((u) -> u.getGender() == Gender.FEMALE)
     .filter((u) -> u.getAge() % 2 == 0);
long time2 = System.currentTimeMillis();
System.out.printf("%d milli seconds", time2 - time1);

औसत समय 44,7 मिलीसेकंड था।

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




Related

java lambda filter java-8 java-stream