2010-03-11 17 views
12

कोडिंग मैं जावा के vararg प्रदर्शन की जांच के लिए चारों ओर आया था।जावा के varargs प्रदर्शन

मैं निम्नलिखित लिखने परीक्षण कोड:

public class T { 

    public static void main(String[] args) { 

     int n = 100000000; 
     String s1 = new String(""); 
     String s2 = new String(""); 
     String s3 = new String(""); 
     String s4 = new String(""); 
     String s5 = new String(""); 

     long t = System.currentTimeMillis(); 
     for (int i = 0; i < n; i++) { 
      foo(); 
     } 
     System.err.println(System.currentTimeMillis() - t); 


     t = System.currentTimeMillis(); 
     for (int i = 0; i < n; i++) { 
      baz(s1, s2, s3, s4, s5); 
     } 
     System.err.println(System.currentTimeMillis() - t); 

     t = System.currentTimeMillis(); 
     for (int i = 0; i < n; i++) { 
      bar(s1, s2, s3, s4, s5); 
     } 
     System.err.println(System.currentTimeMillis() - t); 

    } 

    static void foo() { 
    } 

    static void bar(String a1, String a2, String a3, String a4, String a5) { 
    } 

    static void baz(String... a) { 
    } 
} 

मेरी मशीन पर औसत उत्पादन है:

78 
4696 
78 

तरीकों लगता है कि पास चर किसी कीमत पर है?! अच्छा !

लेकिन varags का उपयोग 60x धीमी है! क्यूं कर ?

एक स्पष्टीकरण यह हो सकता है कि कार्यक्रम को ढेर पर सरणी बनाना चाहिए और समय जीसी द्वारा खर्च किया जाता है।

0 
62 
0 

क्या के लिए इस अतिरिक्त समय खर्च कर रहा है और वैसे भी संकलक एक फिक्स चर कॉल करने के लिए इस को हल करने में सारी जानकारी है ...

इसकी नहीं मेरा इरादा: लेकिन कम छोरों के लिए मैं अभी भी आउटपुट के रूप में मिलता है उस के लिए अनुकूलन करने के लिए है, लेकिन मैंने पाया इस उत्सुक ...

अद्यतन

मैं एक नया परीक्षण जोड़ा

और यह एक तर्क संस्करण अभी भी 30x धीमा है। शायद दृश्य के पीछे एक ArrayList.toArray() है?

तो अपने कोड में कोई आवश्यक वैरिएग विधियों और लंबाई को ठीक करने के लिए रिफैक्टर से अवगत रहें। यह एक परफॉर्मेंस बढ़ावा हो सकता है।

उत्तर

16

तर्कों की स्थिर सूची एक सरणी से काफी अलग है। जब आप उन्हें इस तरह से पारित करते हैं, तो संकलक संदर्भों के लिए स्थान सुरक्षित रखता है और विधि कहलाता है जब उन्हें पॉप्युलेट करता है।

वरर्ग्स सरणी के बराबर है। ऐसी विधि को कॉल करने के लिए, रन टाइम पर सरणी बनाना और पॉप्युलेट करना आवश्यक है। यही कारण है कि आप अंतर देखते हैं।

String[] और String... समानार्थी शब्द हैं। यदि आपने उनकी तुलना की है, तो आपको समान प्रदर्शन देखना चाहिए।

+0

यूप, यह वही होगा, क्योंकि विभिन्न संकलन से पहले वेरगास सिंटैक्टिक चीनी सरणी कॉल में परिवर्तित हो जाते हैं। – Riduidel

+0

यह मूल रूप से सही है हालांकि मुझे लगता है कि आपको यह स्पष्ट करना चाहिए कि अंतर यह है कि varargs को एक सरणी आवंटित करने और पॉप्युलेट करने के लिए JVM की आवश्यकता होती है। चाहे वह ढेर या ढेर पर हो, यह काफी मुद्दा नहीं है (हालांकि हां, यह निश्चित रूप से ढेर पर है)। –

+0

@ सेन ओवेन धन्यवाद, अपडेट किया गया। –

1

दिलचस्प समस्या!

यह सिर्फ एक अनुमान है: दृश्यों के पीछे, वर-Args केवल सरणी हैं। इस अंतर्निहित सरणी को बनाना और इसे var-args पैरामीटर के साथ पॉप्युलेट करना कुछ समय ले सकता है; इसलिए प्रदर्शन मारा। वैसे मेरा अनुमान है।

0

के रूप में कहा, एक सरणी, जब वर-args ... का उपयोग कर बनाए रखा है

आप भी हर तरीकों के मापदंडों को "अंतिम" जोड़ने के प्रभाव को देखने के लिए

मैं व्यक्तिगत रूप से प्राप्त की कोशिश करनी चाहिए सरणी के लिए 2250 -> 2234 एमएस से एक सुधार।

+0

जावा में पैरामीटर्स को वास्तव में अंतिम नहीं बनाया जा सकता है, फिर भी वे बदल सकते हैं, इसलिए इससे कुछ भी प्रभावित नहीं होना चाहिए। – helpermethod

+0

अंतिम पैरामीटर कैसे बदला जा सकता है? – Hardcoded

+0

अंतिम तर्क और चर बदल नहीं सकते हैं। मुझे लगता है कि इस बिंदु को बेहतर ढंग से बताया गया है: एक * ऑब्जेक्ट संदर्भ * अंतिम मतलब बनाना कि आप संदर्भ को बदल नहीं सकते हैं, लेकिन इसका मतलब यह नहीं है कि जिस वस्तु को संदर्भित किया गया है वह राज्य को बदल नहीं सकता है। –

7

दोनों नवीनतम JRE6 और JRE7 का उपयोग करते हुए मैं तुम्हारा से अलग परिणाम प्राप्त है और वे संकेत मिलता है कि varargs 5 गुना तेजी से कर रहे हैं:

69 
69 
311 

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

627 
7470 
7844 

निष्कर्ष है: varargs उपयोग करने के लिए संकोच नहीं करते। यदि आपका कार्य छोटा है तो उसकी कॉल जेआईटी द्वारा रेखांकित की जाएगी, और यदि ऐसा नहीं है तो वर्गार्ग का ओवरहेड नगण्य होगा।

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