2012-02-15 14 views
7

क्या आप इसे समझने के लिए मुझे संक्षेप में समझा सकते हैं?जावा में int a = a + 1 और a ++ का उपयोग करने के बीच कोई प्रदर्शन अंतर है? यदि ऐसा है तो कौन सा बेहतर है और क्यों?

+4

यह अच्छा होगा। – Mob

+4

माइक्रो-ऑप्टिमाइज़ेशन को संयोजित करना: हमेशा जो भी अधिक पठनीय होता है, संकलक को आपके लिए अनुकूलित करने दें। कोड प्रोग्रामर के लिए है, अनुकूलन कंपाइलर्स के लिए हैं। – amit

+3

इस प्रश्न पूछने से आप तेजी से (अगर कोई है) समाधान के रनटाइम लाभ से अधिक समय लेते हैं। –

उत्तर

3

उत्पन्न बाईटकोड को देखते हुए:

public static void main(String[] args) { 
    int x = 1; 
    int y = 1; 
    int z = 1; 
    int a = 1; 
    int b = 1; 
    x = x + 1; 
    y++; 
    ++z; 
    a += 1; 
    b += 2; 
} 

उत्पन्न करता है (उपयोग javap -c classname)

0: iconst_1 
1: istore_1 
2: iconst_1 
3: istore_2 
4: iconst_1 
5: istore_3 
6: iconst_1 
7: istore 4 
9: iconst_1 
10: istore 5 
12: iload_1 
13: iconst_1 
14: iadd 
15: istore_1 
16: iinc 2, 1 
19: iinc 3, 1 
22: iinc 4, 1 
25: iinc 5, 2 
28: return 

तो (jdk1.6.0 का उपयोग कर

public class Test { 
    public static void main(String[] args) { 

     int a = 0; 

     a = a + 1; 
     a += 1; 
     a++; 
     ++a; 
    } 
} 

यह disassembly है _18):

x = x + 1 

12: iload_1 
13: iconst_1 
14: iadd 
15: istore_1 

जबकि

y++; 
++z; 
a += 1; 

iinc 

हालांकि सभी परिणाम, अपने लैपटॉप पर एक मोटा प्रदर्शन परीक्षण कर में कोई अंतर नहीं के बगल में हुई बनाता है दो के बीच रनटाइम (कभी-कभी ++ एक्स तेज होता था, कभी-कभी एक्स = एक्स + 1 तेज था), इसलिए मैं प्रदर्शन प्रभावों के बारे में चिंता नहीं करता।

+0

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

2

नहीं, कोई ध्यान देने योग्य अंतर नहीं होगा। जो आप सबसे अधिक पठनीय पाते हैं उसका उपयोग करें (जो आमतौर पर a++ है)।

कोड अनुकूलन का पहला नियम: नहीं।

+0

डाउनवॉटर में कोई अंतर है या नहीं: आपकी डाउनवोट को समझाने की देखभाल? –

+1

मैंने डाउनवोट नहीं किया लेकिन वास्तव में मैं आपके बिंदु से सहमत नहीं हूं। स्वच्छ कोड परिप्रेक्ष्य से 'ए + = 1' कम से कम मेरे परिप्रेक्ष्य से पठनीयता और गलती सहनशीलता दोनों के लिए एक और ठोस दृष्टिकोण है। क्या आपने कभी 'ए +++ बी' (जावा और सी ++ में) का मूल्यांकन किया था? एक ++ के लिए एकमात्र तर्क अलग प्रोसेसर निर्देश था, लेकिन यह JVM द्वारा अनुकूलित nowerdays है। – fyr

+0

हम यहां +++ बी पर चर्चा नहीं कर रहे हैं। हम एक ++ पर चर्चा कर रहे हैं, जिसका अर्थ है "* increment a *"। यह किसी भी जावा डेवलपर द्वारा पठनीय है, और इस निर्देश के साथ कोई समझदारी समस्या नहीं है। –

0

ए ++ बहुत तेज़ है। यह असेंबलर के आईएनसी कमांड में परिवर्तित हो जाता है। लेकिन मुझे लगता है कि जेवीएम एक = ए + 1 अनुकूलित करेगा ताकि आपको इसकी परवाह करने की आवश्यकता न हो।

0

यह वही है, और आजकल संकलक अनुकूलन के साथ कि सामान के बारे में पता नहीं होना चाहिए, allocs :)

1

संकलक का अनुकूलन करना चाहिए और वहाँ कोई अंतर नहीं बिल्कुल भी होना चाहिए की तरह अपने प्रदर्शन की जांच अन्य बड़ा मुद्दों को बढ़ाने के लिए। लेकिन ध्यान रखें कि उपसर्ग वेतन वृद्धि ऑपरेटर (यह संकलक द्वारा निर्भर करता है) पोस्टफ़िक्स समकक्ष (C++ और भी सी #) की तुलना में तेजी हो सकता है रखें:

a++ से

++a तेजी क्योंकि पोस्टफ़िक्स ऑपरेटर एक अस्थायी चर बनाना होगा

उपसर्ग:

a = a + 1; 
return a; 

पोस्टफ़िक्स:

int tmp = a; 
a = a + 1; 
return tmp; 
.. उनके क्रियान्वयन के बारे में सोचते
+0

nop: http://stackoverflow.com/questions/24886/is-there-a-performance-difference-between-i-and-i-in-c – assylias

+0

जैसा कि मैंने कहा था: ** ** हो सकता है। हालांकि सभी कंपाइलर इस तरह अनुकूलित नहीं करते हैं। – vulkanino

+0

@ vulkanino: आपके लिए पढ़ना चाहिए: http://stackoverflow.com/questions/4638364/undefined-behavior-and-sequence-points-reloaded – fyr

16

सबसे पहले, जावा भाषा विशिष्टता समय के बारे में कुछ भी नहीं कहती है। लेकिन यह सोचते हैं हम इस तरह के संस javac के रूप में एक विशिष्ट संकलक का उपयोग कर रहे हम देखते हैं कि ऊपर के उदाहरण (a++, ++a, a += 1, a = a + 1) के सभी या तो की तरह कुछ में संकलित किया जा सकता है:

  • iinc अनुदेश पर काम कर रहे, चर:

    iload_<variable> 
    iinc <variable>, 1 
    istore_<variable> 
    
  • iadd instuction, ढेर का उपयोग कर (यहाँ एक भंडारण के रूप में चर 1 उपयोग करते हुए):

    iload_1 
    iconst_1 
    iadd 
    istore_1 
    

यह संकलन करने के लिए सबसे अच्छा संभव तरीका चुनने के लिए संकलक पर निर्भर करता है। जैसे उनके बीच कोई फर्क नहीं पड़ता है। और यह बयानों के बीच कोई अंतर नहीं होना चाहिए - वे सभी एक ही चीज़ व्यक्त करते हैं - एक को एक संख्या में जोड़ना।

beeing कहा कि, दोनों iinc और iadd संस्करण कुछ तेजी से और मंच निर्भर करने के लिए JIT का उपयोग कर संकलित किया जा सकता है, और अंत में मैं यह मान लेगा कि एक सामान्य क्रम में एक ही कोडांतरक कोड में दोनों संस्करणों संकलित करता है।


मेरे कंपाइलर के साथ, * jdk1.6.0_20 * "वृद्धि" विधियां भी एक ही निर्देश का उपयोग करती हैं।

Compiled from "Test.java" 
public class Test extends java.lang.Object{ 
public Test(); 
    Code: 
    0: aload_0 
    1: invokespecial #8; //Method java/lang/Object."<init>":()V 
    4: return 

public static void main(java.lang.String[]); 
    Code: 
    0: iconst_0 
    1: istore_1 
    2: iinc 1, 1 // a = a + 1; 
    5: iinc 1, 1 // a += 1; 
    8: iinc 1, 1 // a++; 
    11: iinc 1, 1 // ++a; 
    14: return 

} 
+0

क्या आप pls कर सकते हैं। '++ ए' के लिए विवरण भी जोड़ें? – Azodious

+0

@Azodious: मामले पर निर्भर करता है, अगर मैं ऊपर दिए गए बयान में '++ a;' जोड़ता हूं तो यह इसे किसी अन्य 'iinc 1, 1' में परिवर्तित कर देगा। हालांकि एक और जटिल परिदृश्य में निर्देशों का क्रम अलग होगा (इसे देखें [SO पोस्ट] (http://stackoverflow.com/questions/5413548/java-prefix-postfix-of-increment-decrement-operators-need- मदद-साथ-उदाहरण))। – dacwe

+0

मुझे लगता है कि "आईएनसी निर्देश, चर पर काम करना" एक गलती है। 'iinc' को 'iload' और' istore' (?) – Johannes

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