2013-02-12 6 views
6

मैं यह पता लगाने के लिए कुछ परीक्षण कर रहा था कि गेटर्स/सेटर्स और प्रत्यक्ष फ़ील्ड एक्सेस का उपयोग करने के बीच गति अंतर क्या है। http://pastebin.com/hcAtjVCLफ़ील्ड एक्सेस की तुलना में विधि पहुंच तेज क्यों लगती है?

मैं क्यों क्षेत्र का उपयोग धीमी प्रतीत हो रहा है, तो किसी ने मुझे समझा सकता है सोच रहा था:

public class FieldTest { 

    private int value = 0; 

    public void setValue(int value) { 
     this.value = value; 
    } 

    public int getValue() { 
     return this.value; 
    } 

    public static void doTest(int num) { 
     FieldTest f = new FieldTest(); 

     // test direct field access 
     long start1 = System.nanoTime(); 

     for (int i = 0; i < num; i++) { 
      f.value = f.value + 1; 
     } 
     f.value = 0; 

     long diff1 = System.nanoTime() - start1; 

     // test method field access 
     long start2 = System.nanoTime(); 

     for (int i = 0; i < num; i++) { 
      f.setValue(f.getValue() + 1); 
     } 
     f.setValue(0); 

     long diff2 = System.nanoTime() - start2; 

     // print results 
     System.out.printf("Field Access: %d ns\n", diff1); 
     System.out.printf("Method Access: %d ns\n", diff2); 
     System.out.println(); 
    } 

    public static void main(String[] args) throws InterruptedException { 
     int num = 2147483647; 

     // wait for the VM to warm up 
     Thread.sleep(1000); 

     for (int i = 0; i < 10; i++) { 
      doTest(num); 
     } 
    } 

} 

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


संपादित: http://pastebin.com/Vzb8hGdc करने के लिए assylias और Stephen C टिप्पणियों को ध्यान में रखा, मैं कोड बदल दिया है, जहां मैं थोड़ा अलग परिणाम मिल गया: http://pastebin.com/wxiDdRix

+2

मुझे लगता है कि कंपाइलर वैसे भी गेटर्स को रेखांकित करता है। क्या आपने बाइटकोड की जांच की है? – jlordo

+10

'/ * वीएम को गर्म करने के लिए प्रतीक्षा करें */थ्रेड.sleep (1000);' - यह नहीं है कि यह कैसे काम करता है। यदि यह कुछ भी नहीं करता है तो JVM गर्म नहीं होता है ... आपके माइक्रो बेंचमार्क में कई त्रुटियां हैं। विशेष रूप से: (i) आप वास्तव में जेवीएम को गर्म करने की अनुमति नहीं देते हैं (ii) आप जिस दो पथों का परीक्षण करना चाहते हैं, वे एक ही विधि में हैं, जो कुछ अनुकूलन को रोक सकता है। – assylias

+11

@jlordo - इनलाइनिंग जेआईटी कंपाइलर द्वारा की जाती है। मैं बाइटकोड में स्पष्ट नहीं होगा। –

उत्तर

9

स्पष्टीकरण यह है कि आपका बेंचमार्क टूटा हुआ है।

पहला पुनरावृत्ति दुभाषिया का उपयोग करके किया जाता है।

Field Access: 1528500478 ns 
Method Access: 1521365905 ns 

दूसरा पुनरावृत्ति दुभाषिया द्वारा शुरू करने के लिए किया जाता है और फिर हम जेआईटी संकलित कोड चलाने के लिए फ़्लिप करते हैं।

Field Access: 1550385619 ns 
Method Access: 47761359 ns 

शेष पुनरावृत्तियों को जेआईटी संकलित कोड का उपयोग करके किया जाता है।

Field Access: 68 ns 
Method Access: 33 ns 

etcetera 

कारण वे कर रहे हैं अविश्वसनीय तेजी से कि JIT कम्पाइलर दूर अनुकूलित किया है छोरों है। यह पता चला है कि वे गणना के लिए उपयोगी कुछ भी योगदान नहीं दे रहे थे। (यह स्पष्ट नहीं पहले नंबर लगता है दूसरे से लगातार तेजी से नहीं है, लेकिन मुझे शक है कि अनुकूलित कोड किसी भी सार्थक तरीके से विधि का उपयोग बनाम क्षेत्र को मापने है।)


पुन UPDATED कोड/परिणाम

: यह स्पष्ट है कि जेआईटी कंपाइलर अभी भी लूप को दूर कर रहा है।

+0

तो @Stephen एक्सेसर्स विधियों का उपयोग न केवल encapsulation का पक्ष है, यह भी गति का पक्ष है ?? यह सुनकर अच्छा लगा!!! – Victor

+0

@ विक्टर - मुझे विश्वास नहीं है कि आप उस निष्कर्ष को आकर्षित कर सकते हैं। दरअसल, मुझे विश्वास नहीं है कि आप इस बेंचमार्किंग से ** किसी भी ** निष्कर्ष को आकर्षित कर सकते हैं। यह आसानी से त्रुटिपूर्ण है –

+0

धन्यवाद स्टीफन! मैं देखता हूं ... मैं इसे सोचने लगा था। तो यदि आप गति का उपयोग प्रत्यक्ष पहुंच चाहते हैं, यदि आप एक अधिक लचीली डिजाइन के लिए देख रहे हैं, तो एक्सेसर्स विधियों का उपयोग करें? (ऑफटॉप प्रश्न के लिए खेद है!) – Victor

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