2013-06-18 8 views
6

निम्न कोड साबित करता है कि विधि 1 विधि 2 से तेज है। क्या कोई टिप्पणी कर सकता है कि इस तरह के व्यवहार का कारण क्या है।स्थानीय सदस्य तेज़ या इंस्टेंस सदस्य

class Trial { 
     String _member; 
     void method1() { 
      for(int i=0;i<30480;i++) { 
       _member += "test"; 
      } 
     } 
     void method2() { 
      String temp=""; 
      for(int i=0;i<30480;i++) { 
       temp += "test"; 
      } 
      _member = temp; 
     } 

     public static void main(String args[]) { 
      Trial t = new Trial(); 
      long startTime1 = System.currentTimeMillis(); 
      t.method1(); 
      long endTime1 = System.currentTimeMillis(); 
      long startTime2 = System.currentTimeMillis(); 
      t.method2(); 
      long endTime2 = System.currentTimeMillis(); 
      System.out.println(endTime1 - startTime1); 
      System.out.println(endTime2 - startTime2); 
     } 
    } 
+1

के बाहर उपयोग नहीं किया गया है आपने कितनी बार अपना परीक्षण चलाया? क्या आपने लूप में कई बार दो प्रकारों को चलाने और चलाने की कोशिश की? क्या आपने अपनी कॉल के आदेश को आजमाया और घुमाया? –

+0

[jmh] (http://openjdk.java.net/projects/code-tools/jmh/) का उपयोग करके बेंचमार्क को कार्यान्वित करने का प्रयास करें। यह जेवीएम डेवलपर्स द्वारा डिजाइन किया गया एक विशेष उपकरण है। आप अपने स्वयं के बेंचमार्क के बजाय इस टूल का उपयोग करके कई गलतियों से बच सकते हैं। –

+0

मैंने इसे 10 बार कोशिश की, और दूसरा हमेशा तेज़ चलता है। – simaremare

उत्तर

12

निम्नलिखित कोड साबित करता है कि Method1 Method2 की तुलना में तेजी

नहीं, ये यह साबित नहीं करता है।

यह कई कारकों पर निर्भर करता है। जब मैं इस कोड को चलाने के लिए, मैं अपने वातावरण में

1403 
1248 

तो मिलता है, अपने कोड "साबित होता है" कि Method1 धीमी Method2 से है।

बेंचमार्किंग करते समय, आपको कैशिंग और जेवीएम वार्मअप जैसे प्रभावों का ख्याल रखना होगा।

अधिक जानकारी के लिए भी

देखें।


मैं थोड़ा पुनर्संशोधित main विधि:

... 

static void doBenchmark() { 
    Trial t = new Trial(); 

    long startTime1 = System.currentTimeMillis(); 
    t.method1(); 
    long endTime1 = System.currentTimeMillis(); 

    long startTime2 = System.currentTimeMillis(); 
    t.method2(); 
    long endTime2 = System.currentTimeMillis(); 

    System.out.println(endTime1 - startTime1); 
    System.out.println(endTime2 - startTime2); 
} 

public static void main(String args[]) { 

    for (int i = 0; i < 20; i++) { 
     doBenchmark(); 
     System.out.println("----"); 
    } 
} 

यह पहलेfor -loop की यात्रा के लिए समान मूल्यों में परिणाम है, लेकिन फिर परिणाम अभिसरण और अब काफी भिन्न नहीं है:

1396 
1133 
---- 
1052 
1070 
---- 
688 
711 
---- 
728 
726 
---- 
715 
709 
---- 
... 

यहां तक ​​कि कभी-कभी method1 तेज और कभी-कभी लगता है es method2 - यह माप गलतता के कारण सबसे अधिक संभावना है।

+0

फिर से वही प्रश्न, विधि 2 विधि 1 से तेज क्यों है ... लोल .... बेंचमार्किंग के लिए + 1 ..... –

+1

मुझे लगता है कि मुझे कुछ बेंचमार्क टूल का उपयोग करके फिर से अपने निष्कर्षों को सत्यापित करने की आवश्यकता है। जैसे ही मैं उसके साथ प्रतिक्रिया करता हूं, मैं प्रतिक्रिया पोस्ट करूंगा। – Amber

0

कुछ समय के लिए जेवीएम को गर्म करने के बाद, आप देखेंगे कि method2 विधि 1 से तेज है। यहाँ

class Trial { 
String _member; 

    void method1() { 
    for (int i = 0; i < 30480; i++) { 
     _member += "test"; 
    } 
    } 

    void method2() { 
    String temp = ""; 
    for (int i = 0; i < 30480; i++) { 
     temp += "test"; 
    } 
    _member = temp; 
    } 

    public static void main(String args[]) { 
    Trial t = new Trial(); 

    for (int i = 0; i < 10; i++) { //warm up jvm 
     t.method1(); 
     t.method2(); 
    } 

    t = new Trial(); 

    long startTime1 = System.currentTimeMillis(); 
    t.method1(); 
    long endTime1 = System.currentTimeMillis(); 
    long startTime2 = System.currentTimeMillis(); 
    t.method2(); 
    long endTime2 = System.currentTimeMillis(); 
    System.out.println(endTime1 - startTime1); 
    System.out.println(endTime2 - startTime2); 
    } 
} 

और परिणाम है::

यहाँ मेरी फिर से कारक कोड है

---- 
2910 
2894 
---- 

लेकिन वास्तविक बेंच मार्किंग के लिए, आप इसे कई बार के लिए चलाने के लिए और सांख्यिकीय व्यवहार का पालन करना चाहिए और केवल तभी आप कोई निष्कर्ष निकाल सकते हैं!

+0

ठीक है - आपने वही गलती की है जैसा मैंने अपने रिफैक्टरिंग के दौरान किया था: डी वास्तव में विधियों की तुलना करने के लिए, आपको 'for'-loop के अंदर 'परीक्षण' को फिर से चालू करने की आवश्यकता है। अन्यथा आप 'स्ट्रिंग _member' चर में पुरानी सामग्री के साथ काम करते हैं। चूंकि वहां पहले से ही सामग्री है, अतिरिक्त सम्मेलन में काफी समय लगेगा। –

+0

मैंने अपना जवाब संपादित कर लिया है, फिर भी विधि 2 तेज है ...: पी –

0

मैं 3000 समय अधिक तेजी से StringBuilder2500 के साथ यहां परीक्षण की संख्या को बदल दिया है, लेकिन नहीं विधि,!

class Trial { 
    StringBuilder _member = new StringBuilder(243840); 
    void method1() { 
     for (int i = 0; i < 30480; i++) { 
      _member.append("test"); 
     } 
    } 

    void method2() { 
     final StringBuilder temp = new StringBuilder(243840); 
     for (int i = 0; i < 30480; i++) { 
      temp.append("test"); 
     } 
     _member = temp; 
    } 
    public static void main(final String args[]) { 
     long startTime1 = System.nanoTime(); 
     new Trial().method1(); 
     long endTime1 = System.nanoTime(); 
     long startTime2 = System.nanoTime(); 
     new Trial().method2(); 
     long endTime2 = System.nanoTime(); 
     System.out.println(endTime1 - startTime1); 
     System.out.println(endTime2 - startTime2); 
     System.out.println("------------------"); 
     startTime1 = System.nanoTime(); 
     new Trial().method1(); 
     endTime1 = System.nanoTime(); 
     startTime2 = System.nanoTime(); 
     new Trial().method2(); 
     endTime2 = System.nanoTime(); 
     System.out.println(endTime1 - startTime1); 
     System.out.println(endTime2 - startTime2); 
    } 
} 

उत्पादन:

method1 then method2 with += in MILLIisecond 
5563 
5844 
............................................ 
5437 
6344 

method2 then method1 with += in MILLIisecond 
4625 
5969 
------------------ 
6531 
4891 

===================================================== 

method1 then method2 with StringBuilder in NANOsecond 
3530337 
2074286 
------------------ 
2058641 
1983493 
..................................................... 

method2 then method1 with StringBuilder in NANOsecond 
3430883 
1698819 
------------------ 
2065626 
2144406 

तो के रूप में @Andreas ने कहा कि यह प्रदर्शन का परीक्षण करने के लिए एक अच्छा तरीका नहीं है।

बात बताते: StringBuilder का उपयोग घोषित आकार के साथ (जोशुआ बलोच की पुस्तक प्रभावी जावा मद 51 में: स्ट्रिंग संयोजन के प्रदर्शन खबरदार)
- Method2 पसंद करते हैं() जब यह संभव: स्ट्रिंग [ बिल्डर] इसके अंदर घोषित किया गया है, और

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