2011-09-01 15 views
6

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

6 7 0 0 0 0 0 0 0 0

क्यों पहले दो छोरों हमेशा कुछ समय लग रहा है, फिर बाकी अभी छोड़ी नहीं जा पा रहे:

for (int j = 0; j < 10; j++) { 
    long t = System.currentTimeMillis(); 
    for (int i = 0; i < 10000000; i++) 
     ; 
    t = System.currentTimeMillis() - t; 
    System.out.print(t + " "); 
} 

हर बार जब मैं इस चलाने के लिए, यह एक ही परिणाम देता है सिस्टम द्वारा?

In this answer to this post, ऐसा कहा जाता है कि जस्ट-इन-टाइम संकलन इसे अनुकूलित करने में सक्षम होगा। लेकिन यदि हां, तो पहले दो लूपों में अभी कुछ समय क्यों लगा?

+3

मुझे लगता है कि 'System.nanoTime() 'इस परीक्षण के लिए अधिक संकेत दिया गया है (क्लाइंट/सर्वर वीएम को कुछ अंतर भी करना चाहिए) –

+0

हाँ, दाएं, मिलीसेकंड अक्सर बहुत मोटे होते हैं। –

उत्तर

20

जेआईटी ट्रिगर कोड के एक निश्चित टुकड़े के बाद कई बार निष्पादित किया गया है।

हॉटस्पॉट JVM आपके कोड में "हॉट स्पॉट" की पहचान करने का प्रयास करेगा। हॉट स्पॉट आपके कोड के टुकड़े होते हैं जिन्हें कई बार निष्पादित किया जाता है। ऐसा करने के लिए, JVM विभिन्न निर्देशों के निष्पादन को "गिनती" करेगा, और जब यह निर्धारित करता है कि एक निश्चित टुकड़ा अक्सर निष्पादित होता है, तो यह जेआईटी को ट्रिगर करेगा। (यह एक अनुमान है, लेकिन इस तरह समझाया जाना समझना आसान है)।

जेआईटी (जस्ट-इन-टाइम) कोड का वह टुकड़ा लेता है, और इसे तेज़ी से बनाने की कोशिश करता है।

JIT द्वारा प्रयोग किया जाता तेजी से अपने कोड को चलाने के लिए तकनीक एक बहुत हैं, लेकिन एक है कि सबसे अधिक भ्रम की स्थिति पैदा करता हैं:

  1. यह अगर कोड के उस टुकड़े चर हैं कि का उपयोग करता है यह निर्धारित करने की कोशिश करेंगे कहीं और नहीं उपयोग किया जाता है (बेकार चर), और उन्हें हटा दें।
  2. आप को प्राप्त करने और एक ही ताला कई बार (एक ही वस्तु के सिंक्रनाइज़ तरीकों बुला) की तरह जारी है, यह ताला एक बार प्राप्त करने और आप एक वस्तु के सदस्यों तक पहुंचते हैं तो एक भी सिंक्रनाइज़ ब्लॉक
  3. में सभी कॉल कर सकते हैं जो अस्थिर घोषित नहीं हैं, यह बहु-थ्रेडिंग कोड में अजीब परिणाम बनाने, इसे अनुकूलित करने (रजिस्टरों और समान में मान रखने) का निर्णय ले सकते हैं।
  4. कॉल की लागत से बचने के लिए यह इनलाइन विधियों में होगा।
  5. यह मशीन कोड से बाइटकोड का अनुवाद करेगा।
  6. यदि लूप पूरी तरह से बेकार है, तो इसे पूरी तरह से हटाया जा सकता है।

तो, आपके प्रश्न का उचित उत्तर यह है कि एक खाली लूप, जेआईटीएड होने के बाद, निष्पादित करने में कोई समय नहीं लगता .. शायद अधिक नहीं है।

फिर, कई अन्य अनुकूलन हैं, लेकिन मेरे अनुभव में ये उन लोगों में से हैं जिन्होंने अधिकतर सिरदर्द बनाए हैं।

इसके अलावा, जावा के किसी भी नए संस्करण में जेआईटी में सुधार किया जा रहा है, और कभी-कभी यह मंच के आधार पर थोड़ा अलग होता है (क्योंकि यह कुछ हद तक प्लेटफॉर्म विशिष्ट है)। जेआईटी द्वारा किए गए ऑप्टिमाइज़ेशन को समझना मुश्किल होता है, क्योंकि आप आमतौर पर जावा के हालिया संस्करणों में जावा के उपयोग और बाइटकोड का निरीक्षण नहीं कर सकते हैं, भले ही इनमें से कुछ ऑप्टिमाइज़ेशन को संकलक में सीधे ले जाया गया हो (उदाहरण के लिए, जावा 6 के बाद से कंपाइलर अप्रयुक्त स्थानीय चर और निजी तरीकों के बारे में पता लगाने और चेतावनी देने में सक्षम)।

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

यह आम तौर पर आपके जैसे साधारण कार्यक्रम में जेआईटी को ट्रिगर करता है, भले ही कोई गारंटी न हो कि यह वास्तव में ट्रिगर करेगा (या यह एक निश्चित मंच पर भी मौजूद है)।

यदि आप जेआईटी या गैर जेआईटी समय (मैंने किया) के बारे में पागल होना चाहते हैं: पहला दौर बनाएं, लूप के प्रत्येक निष्पादन का समय दें, और समय स्थिर होने तक प्रतीक्षा करें (उदाहरण के लिए, 10 से कम औसत से अंतर %), फिर अपने "असली" समय से शुरू करें।

7

जेआईटी कोड के एक हिस्से पर नहीं लाता है जब तक कि यह निर्धारित न हो कि ऐसा करने के लिए कुछ लाभ है। इसका मतलब है कि कुछ कोड के माध्यम से पहले कुछ पास जीआईटी नहीं होंगे।

+0

धन्यवाद! मैं देखता हूं, लेकिन खाली लूप संभवतः क्या कर सकता है? या @ सिमोन गियानी ने कहा, जेआईटी (की गारंटी है) तब तक ट्रिगर नहीं की जाएगी जब तक कि कुछ समय तक लूप को निष्पादित नहीं किया जाता है? संपादित करें: फिर से धन्यवाद! मुझे सिमोन के जवाब से जवाब मिला :) –