75

जावा में दो प्रकार के if कथन हैं - क्लासिक: if {} else {} और शॉर्टेंड: exp ? value1 : value2। क्या एक दूसरे की तुलना में तेज़ है या वे वही हैं?कौन सा "अगर" निर्माण तेज है - कथन या टर्नरी ऑपरेटर?

बयान:

int x; 
if (expression) { 
    x = 1; 
} else { 
    x = 2; 
} 

त्रिगुट ऑपरेटर:

int x = (expression) ? 1 : 2; 
+33

मुझे लगता है कि बिल्कुल कोई अंतर नहीं है। यह सिर्फ वाक्यविन्यास है। जब तक कि कंपाइलर्स कुछ हद तक बुरा न हो (या कुछ और) और मैं गलत हूं – sinelaw

+4

क्या आपने (माइक्रो) इसे बेंचमार्क किया था? परिणाम साझा करें। – BalusC

+3

दोनों को jit'ed मिल जाएगा। बिल्कुल कोई फर्क नहीं पड़ेगा। और सामान को अपनाना परेशान मत करो।पहली बात यह है कि HotSpot करता है ** javac द्वारा लागू किए गए सभी ** अनुकूलन को निकालना है। –

उत्तर

93

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

कभी-कभी if कथन अधिक पठनीय होगा, कभी-कभी सशर्त ऑपरेटर अधिक पठनीय होगा। विशेष रूप से, मैं सशर्त ऑपरेटर का उपयोग करने की अनुशंसा करता हूं जब दो ऑपरेंड सरल और दुष्प्रभाव रहित होते हैं, जबकि यदि दो शाखाओं का मुख्य उद्देश्य उनके दुष्प्रभाव हैं, तो शायद मैं if कथन का उपयोग करता हूं। यहाँ

public class Test extends java.lang.Object { 
    public Test(); 
    Code: 
     0: aload_0 
     1: invokespecial #1 
     4: return 

    public static void main(java.lang.String[] 
    Code: 
     0: aload_0 
     1: arraylength 
     2: ifle   10 
     5: iconst_1 
     6: istore_1 
     7: goto   12 
     10: iconst_2 
     11: istore_1 
     12: return 

    public static void main2(java.lang.String[ 
    Code: 
     0: aload_0 
     1: arraylength 
     2: ifle   9 
     5: iconst_1 
     6: goto   10 
     9: iconst_2 
     10: istore_1 
     11: return 
} 

आप देख सकते हैं, वहाँ एक मामूली बाईटकोड में अंतर है - istore_1 होता है या नहीं:

public class Test { 
    public static void main(String[] args) { 
     int x; 
     if (args.length > 0) { 
      x = 1; 
     } else { 
      x = 2; 
     } 
    } 

    public static void main2(String[] args) { 
     int x = (args.length > 0) ? 1 : 2; 
    } 
} 

Bytecode javap -c Test साथ decompiled:

यहां एक नमूना कार्यक्रम और बाईटकोड है ब्रान्स के भीतर या नहीं (मेरे पिछले बेहद खराब प्रयास के विपरीत :) लेकिन अगर मैं जेआईटीटर अलग-अलग देशी कोड के साथ समाप्त हुआ तो मुझे आश्चर्य होगा।

+0

एस/सशर्त कथन/सशर्त अभिव्यक्ति/ –

+0

@ लॉरेंस: दोह - धन्यवाद, तय। –

+1

मुझे लगता है कि आप 'मुख्य' और 'main2' दोनों के लिए बिल्कुल सही नहीं थे? – ColinD

4

न - वे एक ही करने के लिए संकलित किया जाएगा।

10

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

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

+0

-1 गलत होने के लिए। यदि आप दावा करने जा रहे हैं कि कोड के दो टुकड़े एक ही बाइटकोड को संकलित करेंगे, तो "शायद" या "मुझे लगता है" जैसे क्वालीफायर प्रदान किए बिना आप कम से कम वास्तव में जांच सकते हैं कि वे ऐसा करते हैं। हालांकि अगर वे एक ही बाइटकोड को संकलित करते हैं, तो यह गारंटी नहीं देगा कि जावा कंपाइलर के अन्य संस्करण अलग-अलग बाइट कोड को संकलित नहीं करेंगे। – Brian

+0

@ ब्रायन: आप सही हैं। मैंने अपना जवाब संपादित किया। –

+5

ठीक है, मैंने अपना -1 हटा दिया :) – Brian

7

ये वही हैं। उनमें से दोनों काफी तेज हैं, आमतौर पर लगभग 10-30 नैनो-सेकेंड। (उपयोग पैटर्न के आधार पर) क्या यह समय आपके लिए महत्वपूर्ण है?

आपको जो करना चाहिए वह आपको करना चाहिए जो आपको विश्वास है।

3

बस सभी अन्य उत्तर में जोड़ने के लिए:

दूसरी अभिव्यक्ति अक्सर तृतीयक/त्रिगुट ऑपरेटर/बयान कहा जाता है। यह बहुत उपयोगी हो सकता है क्योंकि यह एक अभिव्यक्ति देता है। कभी-कभी यह सामान्य लघु विवरणों के लिए कोड को और अधिक स्पष्ट बनाता है।

+3

अभ्यास में इसका शानदार उदाहरण: जावा में , अगर मुझे अभिव्यक्ति के परिणाम के आधार पर स्ट्रिंग फ़ाइनल बनाना है, तो मैं इसका उपयोग कर सकता हूं टर्नरी सिंटैक्स अंतिम स्ट्रिंग जोटेबल = (Integer.parseInt (clientId)> 500)? "सर्वर क्लाइंट्स": "ऑफ़लाइन क्लाइंट्स"; फिर मैं उन जगहों पर अभिव्यक्ति के मूल्य का उपयोग कर सकता हूं जहां टटेबल को अंतिम होने की आवश्यकता है। निम्नलिखित अवैध होंगे: अंतिम स्ट्रिंग जोटेबल = ""; यदि (Integer.parseInt (clientId)> 500) { जोटेबल = "सर्वर क्लाइंट्स"; } अन्य { जोटेबल = "ऑफ़लाइन क्लाइंट्स"; } –

+0

@JamesPerih बिल्कुल। – Secko

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