2010-04-09 17 views
8

मैं निम्नलिखित दो कार्यक्रमों है फर्क सिर्फ इतना है पाश चर (int और long) का प्रकार है।पुनरावृत्ति गति बनाम लंबे

जब मैं इसे चलाता हूं, तो पहला प्रोग्राम लगातार 0 और 16 एमसीईसी के बीच प्रिंट करता है, भले ही N के मान के बावजूद। दूसरा बहुत लंबा लगता है। N == Integer.MAX_VALUE के लिए, यह मेरी मशीन पर लगभग 1800 एमसीईसी में चलता है। N में रन टाइम कम या ज्यादा रैखिक प्रतीत होता है।

तो यह क्यों है?

मुझे लगता है कि जेआईटी-कंपाइलर int लूप को मौत के लिए अनुकूलित करता है। और अच्छे कारण के लिए, क्योंकि जाहिर है कि यह कुछ भी नहीं करता है। लेकिन यह long लूप के लिए ऐसा क्यों नहीं करता है?

एक सहयोगी ने सोचा कि हम long लूप में अपना काम कर रहे जेआईटी कंपाइलर को माप सकते हैं, लेकिन चूंकि रन टाइम N में रैखिक प्रतीत होता है, तो शायद यह मामला नहीं है।

मैं JDK 1.6.0 अद्यतन 17 उपयोग कर रहा हूँ:

C:\>java -version 
java version "1.6.0_17" 
Java(TM) SE Runtime Environment (build 1.6.0_17-b04) 
Java HotSpot(TM) 64-Bit Server VM (build 14.3-b01, mixed mode) 

मैं Windows XP Professional x64 संस्करण पर हूँ, सर्विस पैक 2, 2.40GHz पर एक इंटेल Core2 Quad सीपीयू के साथ।


अस्वीकरण

मुझे पता है कि microbenchmarks उत्पादन में उपयोगी नहीं हैं। मुझे यह भी पता है कि System.currentTimeMillis() उतना सटीक नहीं है जितना इसके नाम से पता चलता है। यह सिर्फ कुछ है जो मैंने चारों ओर बेवकूफ़ बनाते हुए देखा, और मैं बस इतना उत्सुक था कि ऐसा क्यों होता है; और कुछ नहीं।

+0

मैं बिल्कुल यहाँ @Andrzej से सहमत है, लेकिन यह वास्तव में सिर्फ जिज्ञासा की खातिर अगर, आप वास्तव में जेनरेट किए गए कोड को देखने के लिए PrintAssembly प्लगइन का उपयोग कर सकते हैं: http://wikis.sun.com/display/HotSpotInternals/PrintAssembly –

+0

यदि आप -Xint ध्वज के साथ भागते हैं तो क्या होता है? यह हॉटस्पॉट संकलन को रोकता है, इसलिए आपको बेहतर तुलना मिल जाएगी। –

+0

@ स्टेवेन: लेकिन '-Xint' के साथ परिणाम वास्तविक उपयोग जैसा कुछ भी * कम * सार्थक है। –

उत्तर

5

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

इस तरह की चीज के आसपास बहुत भ्रामक माइक्रो बेंचमार्क लिखना भी अविश्वसनीय रूप से आसान है - कुछ सामान्य नुकसान के लिए this IBM DW article देखें, उनसे कैसे बचें और आप क्या कर रहे हैं पर कुछ सामान्य टिप्पणी देखें।

तो वास्तव में यह एक "कोई टिप्पणी नहीं" उत्तर है, लेकिन मुझे लगता है कि यह एकमात्र वैध प्रतिक्रिया है।एक संकलन-समय-त्रिभुज नो-ऑप लूप को की आवश्यकता नहीं है, इसलिए संकलक को इनमें से कुछ स्थितियों में तेज़ होने के लिए अनुकूलित नहीं किया गया है।

JVM निष्कर्ष निकाला है कि पहले पाश प्रभावी रूप से तो यह यह पूरी तरह से निकाल देता है, कुछ नहीं करता है:

+0

आप बिल्कुल सही हैं। जिस कारण से मैं पूछ रहा हूं वह चारों ओर मूर्खतापूर्ण होने पर मैंने जो कुछ देखा, उसके बारे में शुद्ध जिज्ञासा है; मैं एक असली कार्यक्रम में ऐसा करने का इरादा नहीं रखता हूं। :) – jqno

4

आप शायद 32-बिट JVM का उपयोग कर रहे हैं। परिणाम 64 बिट जेवीएम के साथ शायद अलग होंगे। एक 32-बिट JVM में एक int को मूल 32-बिट पूर्णांक में मैप किया जा सकता है और एक ही ऑपरेशन के साथ बढ़ाया जा सकता है। वही लंबे समय तक नहीं पकड़ता है, जिसके लिए अधिक संचालन की आवश्यकता होगी।

int और लंबे आकार के बारे में चर्चा के लिए यह question देखें।

+0

अच्छा बिंदु। हालांकि, मैं 64 बिट्स जेवीएम का उपयोग कर रहा हूं। मैं सवाल अपडेट करूंगा। – jqno

+0

यह ऑपरेशन सिस्टम और आपके हार्डवेयर कॉन्फ़िगरेशन (मुख्य रूप से सीपीयू) के बारे में कुछ विवरण पोस्ट करने के लिए भी उपयोगी होगा। – kgiannakakis

3

मेरा अनुमान है - - और यह केवल एक अनुमान है यह है। फॉर-लूप से कोई चर "escapes" नहीं है।

दूसरे मामले में, लूप भी कुछ भी नहीं करता है। लेकिन हो सकता है कि जेवीएम कोड यह निर्धारित करता है कि लूप में कुछ भी नहीं है "अगर (i का प्रकार) == int" खंड। इस मामले में डू-कुछ भी नहीं-लूप को हटाने का अनुकूलन केवल int के साथ काम करता है।

कोड को हटाने वाला एक अनुकूलन यह सुनिश्चित करना है कि कोई दुष्प्रभाव नहीं हैं। प्रतीत होता है कि JVM कोडर सावधानी के पक्ष में क्षीण हो गए हैं।

1

इस तरह के माइक्रो-बेंचमार्किंग बहुत समझ में नहीं आता है, क्योंकि परिणाम हॉटस्पॉट जेआईटी के आंतरिक कार्यों पर बहुत निर्भर करते हैं।

साथ ही, ध्यान दें कि सिस्टम घड़ी मान जो आपको System.currentTimeMillis() के साथ मिलते हैं, सभी ऑपरेटिंग सिस्टम पर 1 एमएस रिज़ॉल्यूशन नहीं है। आप इसे बहुत ही कम समय अवधि के लिए बहुत सटीक समय तक उपयोग नहीं कर सकते हैं।

इस लेख, कि बताते हैं पर एक नज़र डालें क्यों जावा में सूक्ष्म मानक कर के रूप में आसान नहीं है के रूप में ज्यादातर लोगों को लगता है: Anatomy of a flawed microbenchmark

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