नीचे दिया गया कोड दो साधारण कार्यों को 10 बिलियन बार कॉल करता है।दो स्ट्रिंग तर्कों को एक सूची तर्क से अधिक कुशल क्यों गुजर रहा है
public class PerfTest {
private static long l = 0;
public static void main(String[] args) {
List<String> list = Arrays.asList("a", "b");
long time1 = System.currentTimeMillis();
for (long i = 0; i < 1E10; i++) {
func1("a", "b");
}
long time2 = System.currentTimeMillis();
for (long i = 0; i < 1E10; i++) {
func2(list);
}
System.out.println((time2 - time1) + "/" + (System.currentTimeMillis() - time2));
}
private static void func1(String s1, String s2) { l++; }
private static void func2(List<String> sl) { l++; }
}
मेरी धारणा यह थी कि इन दो कॉलों का प्रदर्शन समान के करीब होगा। अगर कुछ भी मैंने अनुमान लगाया होगा कि दो तर्क पारित करने से एक गुजरने से थोड़ा धीमा होगा। सभी तर्कों को देखते हुए ऑब्जेक्ट संदर्भ हैं, मैं इस तथ्य की अपेक्षा नहीं कर रहा था कि कोई भी कोई फर्क नहीं पड़ता।
मैंने कई बार परीक्षण चलाया है और एक सामान्य परिणाम "12781/30536" है। दूसरे शब्दों में, दो तारों का उपयोग करने वाले कॉल में 13 सेकंड लगते हैं और सूची का उपयोग करके कॉल 30 सेकंड लेता है।
प्रदर्शन में इस अंतर के लिए स्पष्टीकरण क्या है? या यह एक अनुचित परीक्षण है? मैंने दो कॉलों को स्विच करने का प्रयास किया है (यदि यह स्टार्टअप प्रभाव के कारण था) लेकिन परिणाम समान हैं।
अद्यतन
यह कई कारणों के लिए एक उचित परीक्षण नहीं है। हालांकि यह जावा कंपाइलर के असली व्यवहार का प्रदर्शन करता है। नोट निम्नलिखित दो अतिरिक्त इस प्रदर्शन करने के लिए:
- भाव जोड़ना
s1.getClass()
औरsl.getClass()
कार्यों के लिए दो फ़ंक्शन कॉल perfom ही - रनिंग
-XX:-TieredCompilation
साथ परीक्षण भी बनाता है दो कार्यों कॉल एक ही प्रदर्शन करता है
इस व्यवहार के लिए स्पष्टीकरण नीचे दिए गए स्वीकृत उत्तर में है। @ Apangin के उत्तर का संक्षिप्त सारांश यह है कि func2
हॉटस्पॉट कंपाइलर द्वारा रेखांकित नहीं है क्योंकि इसकी तर्क (यानी List
) का हल नहीं किया गया है। कक्षा के संकल्प को मजबूर करना (उदाहरण के लिए getClass
का उपयोग करके) इसे रेखांकित किया जाता है जो इसके प्रदर्शन में काफी सुधार करता है। जैसा कि उत्तर में बताया गया है, अनसुलझे वर्ग वास्तविक कोड में होने की संभावना नहीं है जो इस कोड को एक अवास्तविक बढ़त मामला बनाता है।
क्या आप अपनी अपेक्षाओं को जोड़ सकते हैं और क्यों? – ChiefTwoPencils
@ChiefTwoPencils ने उस पर एक पैरा जोड़ा है। – sprinter
मैंने बंद करने के लिए वोट नहीं दिया, लेकिन जब तक कोई विशिष्ट संकलन अनुकूलन को देखने के लिए रनटाइम को अलग करने के लिए तैयार नहीं होता है, तो अधिकांश प्रदर्शन प्रश्न वास्तव में बहुत उपयोगी नहीं होते हैं (हालांकि वे मनोरंजक/रोचक हो सकते हैं) - और उत्तर कर सकते हैं रिलीज से रिलीज में बदलें। इस मामले में मैं बस मानता हूं कि जेवीएम को सरणी कॉल की तुलना में दो पैरामीटर कॉल को संकलित या याद रखना आसान लगता है, लेकिन गंभीरता से - जो भी सबसे ज्यादा पठनीय है उसे लिखें! यह भी ध्यान रखें, सबसे पठनीय संस्करण प्रायः वह है जिसे JVM सर्वोत्तम अनुकूलित करता है। –