2013-02-15 34 views
8

यह दो भाग का सवाल है, लेकिन व्यक्तिगत टुकड़ों से इसका अर्थ नहीं होगा। बाइटकोड आउटपुट के भीतर dup निर्देशों की बड़ी संख्या खराब लिखित कोड का संकेतक है? जहां सभी बाइटकोड निर्देशों के कुछ प्रतिशत द्वारा बड़े पैमाने पर परिभाषित किया जाता है। आगे एक कोड को फिर से लिखने के बारे में कैसे जाता है जो dup निर्देश उत्पन्न करता है?जावा बाइटकोड "अत्यधिक" संख्या को "खराब" कोड माना जाता है?

+0

जिज्ञासा से, इस तरह के सवाल को क्या उत्तेजित करेगा? – delnan

+0

मुझे लगता है कि आपने दाईं ओर दिए गए लिंक देखे हैं: http://stackoverflow.com/questions/8594657/why-does-the-following-code-translate-to-a-new-dup-op-instructions-in- जावा-बाइट और http://stackoverflow.com/questions/12438567/java-bytecode-dup – assylias

+0

@assylias हां बिल्कुल। हालांकि, वे मेरे विशिष्ट प्रश्नों को संबोधित नहीं करते हैं। – Woot4Moo

उत्तर

7

क्या हम javac आउटपुट के बारे में बात कर रहे हैं जिसका आप विश्लेषण कर रहे हैं या अपना स्वयं का कंपाइलर/जेनरेटर? यदि आप javac उत्पादन के परिप्रेक्ष्य से अपने जावा कोड की गुणवत्ता के बारे में चिंतित हैं - इसके बारे में भूल जाओ। सबसे पहले javac उप-स्थानिक बाइटकोड उत्पन्न करता है और सभी अनुकूलन (बहुत अच्छी पसंद) करने के लिए जेवीएम/जेआईटी पर निर्भर करता है। लेकिन अभी भी बाइटकोड शायद किसी भी चीज से बेहतर हो सकता है। यह सी संकलक द्वारा उत्पन्न असेंबली कोड की गुणवत्ता के बारे में पूछने के समान है।

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

new java/lang/Object 
dup 
invokespecial java/lang/Object <init>()V 

dup यहां इस्तेमाल किया जाना चाहिए क्योंकि संकार्य ढेर के invokespecial पॉप शीर्ष। एक बुरा विचार की तरह कन्स्ट्रक्टर को कॉल करने के बाद बस इसके संदर्भ को खोने के लिए ऑब्जेक्ट बनाना। लेकिन असेंबली में dup नहीं है, कोई डेटा कॉपी और डुप्लिकेशन नहीं है। आपके पास केवल एक ही CPU रजिस्ट्री होगी जो java/lang/Object पर इंगित करेगी।

दूसरे शब्दों में उप-उपनिवेश बाइटकोड का उपयोग फ्लाई पर "अधिक इष्टतम" असेंबली में किया जाता है। बस ... परेशान मत करो।

+0

हम्म की बजाय सी जैसा दिखता है, क्या आपके पास कुछ संसाधन हैं जो बताते हैं? मैंने शोध का अपना उचित हिस्सा किया है और ऐसा लगता है कि बाइटकोड निर्देश सेट को समझना महत्वपूर्ण है कि कार्यक्रम रनटाइम पर क्या करता है। यदि मैं थीसिस को ढूंढ सकता हूं जो इसे कॉल करता है तो मैं इसे एक लिंक के रूप में पोस्ट करूंगा। – Woot4Moo

+2

@ Woot4Moo: आप किस प्रकार के संसाधन मांग रहे हैं? मैं मानता हूं कि बाइटकोड को समझना बहुत महत्वपूर्ण है। मैं बस इतना कह रहा हूं कि 'डुप्ली' वास्तव में सिंगल सीपीयू निर्देश को ट्रिगर नहीं कर सकता है।यह सिर्फ एक अमूर्त है जो जेआईटी संकलन के दौरान चलेगा। –

+0

वह संसाधन है जिसे मैं ढूंढ रहा हूं। जहां यह साबित होता है या कम से कम कुछ मामलों में संकेत देता है कि जेआईटी इसे दूर कर देता है। और अगर मैं वास्तव में रहता हूं तो मैं बड़े बाइटकोड स्पेक की प्रतिक्रिया स्वीकार करूंगा। – Woot4Moo

2

dup निर्देश केवल ऑपरेंड स्टैक के शीर्ष तत्व को डुप्लिकेट करता है। यदि संकलक जानता है कि यह अपेक्षाकृत कम अवधि के भीतर कई बार एक मान का उपयोग करने जा रहा है, तो यह मूल्य को डुप्लिकेट करने और इसे आवश्यक होने तक ऑपरेंड स्टैक पर पकड़ने का चयन कर सकता है।

सबसे आम मामलों में जहां आप देख dup है जब आप एक वस्तु बना सकते हैं और एक चर में संग्रहीत में से एक:

0: new #1; //class Foo 
3: dup 
4: invokespecial #23; //Method "<init>":()V 
7: astore_1 

:

Foo foo = new Foo(); 

javap -c चल रहा है, तो आपको निम्न बाईटकोड मिल अंग्रेजी में: new ऑपरेशन Foo ऑब्जेक्ट का एक नया उदाहरण बनाता है, और invokespecialFoo कन्स्ट्रक्टर निष्पादित करता है। चूंकि आपको कन्स्ट्रक्टर का आह्वान करने और चर में स्टोर करने के लिए स्टैक पर संदर्भ की आवश्यकता है, इसलिए dup (विशेष रूप से विकल्प के बाद, चर में संग्रहित करने और फिर सीटीआर चलाने के लिए पुनर्प्राप्त करने के बाद, इसका उल्लंघन करने का बहुत अधिक अर्थ होता है, जावा मेमोरी मॉडल)।

यहां एक मामला है जहां ओरेकल जावा कंपाइलर (1।

int x = 12; 

public int bar(int z) 
{ 
    int y = x + x * 3; 
    return y + z; 
} 

मैं dup को x का मूल्य संकलक उम्मीद थी, क्योंकि यह अभिव्यक्ति में कई बार दिखाई देता: 6) जब मैं करने के लिए यह उम्मीद होती है नहीं उपयोग dup किया था। ,

0: aload_0 
1: getfield #12; //Field x:I 
4: aload_0 
5: getfield #12; //Field x:I 
8: iconst_3 
9: imul 
10: iadd 

मैं dup अपेक्षा की होगी क्योंकि यह एक वस्तु (के बाद भी हॉटस्पॉट अपना जादू करता है) से मान प्राप्त करने के लिए अपेक्षाकृत महंगा है, जबकि दो ढेर कोशिकाओं: इसके बजाय, कोड है कि बार-बार वस्तु से मूल्य लोड itemitted एक ही कैश लाइन पर होने की संभावना है।

+0

और तर्क यह सस्ता क्यों है? – Woot4Moo

+0

"जबकि दो स्टैक सेल एक ही कैश लाइन पर होने की संभावना है" – parsifal

+0

हालांकि, मुझे पता है कि हॉटस्पॉट डुप्लीकेट 'गेटफील्ड' कॉल को पहचानता है, यह स्वीकार करता है कि ऑब्जेक्ट 'अस्थिर' नहीं है, और फ़ील्ड मान को कैश करता है रजिस्टर। – parsifal

1

यदि आप dup और प्रदर्शन पर इसके संबंधों के बारे में चिंतित हैं, तो परेशान न करें। जेवीएम समय संकलन में करता है, इसलिए इसे वास्तव में प्रदर्शन में कोई फर्क नहीं पड़ता है।

जहां तक ​​कोड की गुणवत्ता है, वहां दो मुख्य चीजें हैं जो जावैक को dup निर्देश उत्पन्न करने का कारण बनती हैं। पहला ऑब्जेक्ट इंस्टेंटेशन है, जहां यह अपरिहार्य है। दूसरा अभिव्यक्तियों में तत्काल मूल्यों के कुछ उपयोग हैं। यदि आप बाद में बहुत कुछ देखते हैं, तो यह खराब गुणवत्ता कोड हो सकता है, क्योंकि आप आमतौर पर अपने स्रोत कोड में जटिल अभिव्यक्ति नहीं चाहते हैं (यह कम पठनीय है)।

के अन्य संस्करणों dup (dup_x1, dup_x2, dup2, dup2_x1, और dup2_x2) रहेगी, क्योंकि वस्तु इन्स्टेन्शियशन उन का उपयोग नहीं करता विशेष रूप से समस्याग्रस्त हैं तो यह लगभग निश्चित रूप से बाद में मतलब है। बेशक तब भी यह एक बड़ी समस्या नहीं है। इसका मतलब यह है कि स्रोत कोड उतना पठनीय नहीं है जितना हो सकता है।

यदि कोड जावा से संकलित नहीं है, तो सभी शर्त बंद हैं। निर्देशों की उपस्थिति या अनुपस्थिति वास्तव में आपको बहुत कुछ नहीं बताती है, खासकर उन भाषाओं में जिनके कंपाइलर संकलन समय अनुकूलन करते हैं।

+0

यह सभी जावा fwiw है। – Woot4Moo

+0

विरासत कोड प्रकृति और अप्राप्य (> 500 लाइन फ़ंक्शन और ऐसे) में बहुत ही प्रक्रियात्मक है – Woot4Moo

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

  • कोई संबंधित समस्या नहीं^_^