2010-01-11 11 views
15

तार्किक रूप से, if(!foo) और if(foo == false) समकक्ष हैं। जावा में उनका प्रतिनिधित्व कैसे किया जाता है? क्या बाइटकोड में या प्रदर्शन में संकलन के बाद दोनों के बीच कोई अंतर है? मैं जेएलएस में एक जवाब खोजने में असमर्थ था, और खोज = बनाम == टाइपो और ==/बराबर() व्यवहार के बारे में बहुत सारे परिणाम लाए। (इस मामले में, प्रतीकों ने मेरी खोज में बाधा डाली; भविष्य के खोजकर्ताओं के लिए, निषेध ऑपरेटर, झूठी बराबर, झूठी के बराबर, शर्त नहीं)।जावा में if (! Foo) और if (foo == false) के बीच प्रदर्शन अंतर क्या है, यदि कोई है?

सीडब्ल्यू बहस को दूर करने के लिए: यह प्रश्न यह नहीं पूछ रहा है कि कौन से प्रकार के लोग पसंद करते हैं या जिन्हें बेहतर शैली माना जाता है। मुझे भाषा के कार्यान्वयन में मतभेदों में दिलचस्पी है, इसलिए एक सही जवाब है। संबंधित बल्कि नहीं-काफी-ए-शिकार: Difference between while (x = false) and while (!x) in Java?

संपादित करें:

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

+0

ध्यान रखें कि यह संकलक-विशिष्ट है। – danben

+1

यहां दो प्रश्न हैं। पहला पूछता है कि जावा (बाइटकोड) में इसका प्रतिनिधित्व कैसे किया जाता है। दूसरा पूछता है कि प्रदर्शन और बाइटकोड में मतभेद हैं (मुझे लगता है कि आकार यहां संबंधित कारक है)। –

+3

कोई संकलक जो ऑप्टिमाइज़ेशन को पहचान नहीं लेता है, वह बाजार पर बहुत दूर नहीं होगा;) –

उत्तर

44

जेएलएस बयान के आवश्यक व्यवहार को निर्दिष्ट करेगा। हालांकि, वे कैसे कार्यान्वित किए जाते हैं संकलक और जेवीएम का कार्यान्वयन विवरण है।

प्रैक्टिस में, इसके नमक के किसी भी कंपाइलर को उन बयानों के लिए एक ही बाइटकोड उत्सर्जित करना चाहिए। और यदि नहीं, तो भी JVM उन्हें ठीक से अनुकूलित करेगा।

  1. निम्नलिखित सामग्री के साथ एक Test.java संकलित करें:

    इसके अलावा, इस जवाब देने के लिए एक बेहतर तरीका है, खुद के लिए जाँच करने के लिए, javap उपयोग कर रहा है

    class Test { 
        void equals(boolean f) { 
         if (f == false) {} 
        } 
        void not(boolean f) { 
         if (!f) {} 
        } 
    } 
    $ javac Test.java 
    
  2. डी-इकट्ठा यह:

    $ javap -c Test 
    Compiled from "Test.java" 
    class Test extends java.lang.Object{ 
    Test(); 
        Code: 
        0: aload_0 
        1: invokespecial #1; //Method java/lang/Object."<init>":()V 
        4: return 
    
    void equals(boolean); 
        Code: 
        0: iload_1 
        1: ifne 4 
        4: return 
    
    void not(boolean); 
        Code: 
        0: iload_1 
        1: ifne 4 
        4: return 
    
    } 
    

अद्यतन: "अकादमिक" प्रश्न के बारे में आपके प्रश्न का उत्तर देना। जैसा ऊपर बताया गया है, जेएलएस केवल व्यवहार से चिंतित है। मानक में कुछ भी नहीं है जो वास्तव में निर्दिष्ट करता है कि इसे कैसे कार्यान्वित किया जाना चाहिए (ठीक है, जेवीएमएस बहुत मार्गदर्शन प्रदान करता है)।

जब तक संकलक समान समान व्यवहार को संरक्षित करता है, तब तक संकलक अलग-अलग रनटाइम प्रदर्शन के साथ इसे लागू करने के लिए स्वतंत्र होता है।

+0

यही वह है जिसे मैं अच्छी इच्छा कहता हूं! आपके धैर्य के लिए बधाई! –

+4

'javap -c' disassembles, यह decompile नहीं है। –

+1

अच्छा जवाब, धन्यवाद। अकेले जावप का उल्लेख +1 के लिए पर्याप्त था, मैंने इससे पहले कभी नहीं सुना होगा। – Pops

12

कंपाइलर को आंतरिक रूप से एक ही कोड को हल करना चाहिए, इसलिए कोई अंतर नहीं है।

+0

इसे उसी तरह दिखाने के बारे में कैसे नहीं किया गया। –

+5

किसी भी संदर्भ, सबूत, आदि के बिना एक मुफ्त कथन को ऊपर उठाने के बारे में कैसे (भले ही सत्य)। –

0

decompiling the byte code आज़माएं और देखें कि कोड कितना अलग दिखता है। मुझे लगता है कि संकलन उन्हें लगभग समान रूप से हल करेगा और किसी भी मामूली अंतर के परिणामस्वरूप नगण्य प्रदर्शन अंतर होगा।

+1

या यहां तक ​​कि बाइट कोड को भी देखें http://stackoverflow.com/questions/800916/should-i-look-at-the-bytecode-that-is-produce-by-a-java-compiler – gingerbreadboy

0

ठीक है, एक और अधिक पूरा जवाब:

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

यह देखते हुए कि दोनों अभिव्यक्तियां (संभवतः) एक ही बाइटकोड में संकलित हैं, मुझे आकार या प्रदर्शन में कोई अंतर नहीं होने की उम्मीद है।

0

JLS का कहना है कि

में अभिव्यक्ति एक अगर ब्लॉक मूल्यांकन किया जाता है, कि अभिव्यक्ति की तो परिणाम सच

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

लेकिन इस मामले में, मैं उम्मीद करता हूं कि जेआईटी दोनों अभिव्यक्तियों के लिए एक ही बाइटकोड उत्पन्न करेगी।

0

उन दो परिणामों के लिए उत्पन्न बाइटकोड में कोई अंतर नहीं होना चाहिए और यदि ऐसा तब तक किया जाता है जब तक आप बहुत सीमित संसाधनों वाले डिवाइस के लिए कोड नहीं बना रहे हैं (जिस स्थिति में आपको जावा में नहीं लिखा जाना चाहिए) अंतर की तुलना में नगण्य और आपको यह तय करना चाहिए कि इस कोड को लिखने के दो तरीकों में से कौन सा स्पष्ट समाधान है।

0

सूक्ष्म अनुकूलन के बारे में में लगभग किसी भी मामलों समय की बर्बादी में सोच रही थी जाता है और गलत तरीके से सोच की ओर जाता है ...

+0

देखें प्रश्न के धागे में मेरी टिप्पणी। – Pops

0

मैं एक ऐसी ही सी ++/VS2008 के बारे में सवाल पूछा था।

Would VS2008 c++ compiler optimize the following if statement?

बनाम सी ++ में == लिखने की त्रुटियों = बचने के लिए आप

if (NULL == ptr) { ... } 
if (false == boo) { ... } 
if (20 == num) { ... } 

आदि

लिखने के लिए यह थोड़ा कम पढ़ी जा सकती है जब तक आप इसकी आदत हो जाते हैं।

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