2009-07-02 10 views
24

संभव डुप्लिकेट:
Is there a performance difference between i++ and ++i in C++?इटरेटर को बढ़ा रहा है: ++ यह ++ से अधिक कुशल है?

मैं एक कार्यक्रम है जहाँ पुनरावर्तक एक std :: वेक्टर लूप करने के लिए प्रयोग किया जाता है लिख रहा हूँ। किसी ने मुझे बताया कि + + के लिए इसे कथन में करने से अधिक कुशल कोड होता है। दूसरे शब्दों में, वे कह रहे हैं कि: क्या यह सच है

for (vector<string>::iterator it=my_vector.begin(); it != my_vector.end(); ++it) 

रन से अधिक तेजी से

for (vector<string>::iterator it=my_vector.begin(); it != my_vector.end(); it++) 

? यदि ऐसा है, तो दक्षता में सुधार के पीछे क्या कारण है? यह सभी ++/++ करता है यह वेक्टर में अगले आइटम पर इटरेटर को ले जाता है, है ना?

+7

देखें: http://stackoverflow.com/questions/24901/ – Shog9

+2

एक सटीक डुप्लिकेट, लेकिन रेप रेस वैसे भी है। – macbirdie

+1

यह इटरेटर के बारे में है, और इसलिए जवाब देना चाहिए। अन्य प्रश्न समग्र अंतर के बारे में पूछते हैं। मुझे लगता है कि वे संबंधित प्रश्न हैं, लेकिन सही डुप्लीकेट नहीं हैं? –

उत्तर

2

कभी-कभी हाँ। कुछ के साथ इसे अनुकूलित किया जाएगा और वही होगा। Std :: vector <> (और अन्य std-iterators) के लिए यह संभवतः वही होने के लिए अनुकूलित किया जाएगा।

0

हां। जहां तक ​​मुझे याद है, ++ यह ++ से अधिक कुशल है, क्योंकि यह ++ एक अस्थायी वस्तु बनाता है, जबकि ++ ऐसा नहीं करता है।

1

हाँ ++ यह है क्योंकि यह तो अपने आप को बढ़ा देते ऑब्जेक्ट की प्रति वापस जाने के लिए की जरूरत है ++ अधिक सक्षम है।

31

पूर्ववर्ती होने के पीछे कारण तेजी से है कि बाद में वृद्धि को पुराने मूल्य की प्रतिलिपि वापस करने के लिए है। GotW #2 के रूप में, "प्रीइन्क्रिकमेंट पोस्टिनक्रिकमेंट की तुलना में अधिक कुशल है, क्योंकि पोस्टिनक्रिएटमेंट के लिए ऑब्जेक्ट को खुद को बढ़ाना चाहिए और फिर अस्थायी रूप से इसके पुराने मूल्य को वापस लेना चाहिए। ध्यान दें कि यह int जैसे अंतर्निहित लोगों के लिए भी सही है।"

GotW #55 postincrement के विहित प्रपत्र, से पता चलता है जो इसे preincrement प्लस कुछ अधिक काम करना है कि प्रदान करता है:

T T::operator++(int) 
{ 
    T old(*this); // remember our original value 
    ++*this;  // always implement postincrement 
        // in terms of preincrement 
    return old;  // return our original value 
} 

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

+2

ध्यान दें कि सभ्य कंपाइलर पुराने मान की प्रति को ऑप्टिमाइज़ कर देंगे यदि इसे कभी भी उपयोग नहीं किया जाता है। – Novelocrat

+2

बिल्कुल: आप वादा नहीं कर सकते कि प्रीइंक्रिकमेंट पोस्टिनक्रिकमेंट की तुलना में अधिक कुशल है, क्योंकि (ए) मानक की आवश्यकता नहीं होती है, और (बी) स्रोत कोड और कंपाइलर के संयोजनों का आविष्कार करना बहुत आसान है जहां दोनों समान रूप से कुशल हैं। –

+0

लेकिन आप मान सकते हैं कि प्रीइंक्रिकमेंट कम से कम पोस्टिनक्रिकमेंट के रूप में कुशल है। तो क्यों न केवल हमेशा इसका उपयोग करें, जब वे अन्यथा समकक्ष हों? –

2

एक मौका है कि यह ++ एक अस्थायी प्रतिलिपि बनाएगा।

इसके अलावा, सी ++ में, एक मौका है कि किसी ने पोस्टिनक्रिएट ऑपरेटर को अधिभारित कर दिया है।

इन बातों के दोनों preincrement बनाम प्रदर्शन कम हो सकता है। अभ्यास में कोई फर्क नहीं पड़ता है। अस्थायी प्रति, विशेष रूप से, अधिकांश कंपेलरों द्वारा अनुकूलित किया जाएगा क्योंकि आपके फॉर लूप की तीसरी अभिव्यक्ति में कोई दुष्प्रभाव नहीं हैं।

6

वेक्टर के लिए कोई फर्क नहीं पड़ता है।

सामान्य रूप से, ++itit++ से धीमे होने की संभावना नहीं है (यदि वे अधिभारित हैं, तो एक समझदार कार्यान्वयन मानते हैं), और बस तेज़ हो सकता है। इसका कारण यह है कि अगर इटरेटर वर्ग स्वयं जटिल होता है, तो it++ को it से पहले मान वापस करना पड़ता है, कार्यान्वयन आम तौर पर एक प्रतिलिपि बना देगा।

वेक्टर इटरेटर्स शायद "बस पॉइंटर्स" (अनुकूलित, गैर-डीबग बिल्ड में) हैं, और operator++ दोनों को रेखांकित किया जाएगा। चूंकि वापसी मूल्य का उपयोग नहीं किया जाता है, इसलिए प्रतिलिपि आमतौर पर समाप्त हो जाएगी। तो इससे कोई फर्क नहीं पड़ता। मैं ++it टाइप करने की आदत में हूं क्योंकि:

1) कुछ दिन यह कुछ इटरेटर प्रकार के लिए एक अंतर डाल सकता है, और मैं उस प्रकार के लिए कुछ विशेष नहीं करना चाहता हूं।

2) व्यक्तिगत रूप से मुझे लगता है कि उपसर्ग ऑपरेटर अधिक स्पष्ट रूप से इरादा व्यक्त करता है: "इसका उपयोग करें और इसके बाद वृद्धि" के विपरीत "इसे बढ़ाएं"।

  1. की यह
  2. वेतन वृद्धि यह
  3. वापसी मूल (गैर वृद्धि) यह

++ यह करता है की एक प्रतिलिपि बनाने:

+0

मुझे कहना होगा कि मेरे लिए नंबर 2 + ++ से ++ देखने के लिए और अधिक भ्रमित था। उदाहरण के लिए, लूप के लिए नियमित int को देखते हुए, (int i = 0; i <10; i ++) मुझे बताता है कि मेरे पास पूर्णांक है जो मैं 0 पर सेट करता हूं (उद्देश्य पर क्योंकि मैं इसे पहली बार चाहता हूं), I जब तक मैं 10 से कम न हो, तब तक ऐसा करना चाहता हूं, और लूप पूरा होने के बाद मैं प्रत्येक बार एक से बढ़ाना चाहता हूं)। तो यह देखने के लिए कि ++ यह पहली बार मेरे लिए बहुत भ्रमित था, मुझे याद है (आप कुछ करने से पहले क्यों फिर से शुरू करना चाहते हैं? आप इसे जो चाहते हैं उससे कम 1 के बजाय आप जो चाहते हैं उसे सेट क्यों नहीं करेंगे?)। मुझे अब यह मिल गया है लेकिन अभी भी – Josh

+0

@ जोश: ठीक है, लेकिन यह नवागंतुक के पूर्ण भ्रम का एक परिणाम है जब लूप निष्पादित करने का अंतिम भाग निष्पादित होता है। बेशक आप अभी भी 0 तक शुरू करते हैं, और इसके बावजूद पहली बार लूप के माध्यम से मूल्य 0 है, दूसरी बार, आदि, भले ही आप '++ i' या' i ++ 'लिखते हों। स्पष्ट रूप से, यदि '++ i' लिखना नवागंतुक को बाद में उस भ्रम को हल करने के लिए शीघ्रता से संकेत देता है, और समझता है कि खंड * के बाद * लूप के शरीर को निष्पादित किया गया है, तो इससे कोई फर्क नहीं पड़ता कि मैं इसे एक के रूप में रेट करूंगा '++ i' के लिए अतिरिक्त लाभ! –

+0

मुझे लगता है कि कॉलेज जाने से पहले मुझे हाईस्कूल में बुरे शिक्षकों को वापस ले जाना चाहिए। उन्होंने हमें बताया ++ मेरा मतलब था कि लूप के अंदर क्या है इसका मूल्यांकन करने से पहले यह वृद्धि होगी, और लूप के अंदर क्या है इसके मूल्यांकन के बाद i ++ वृद्धि होगी। अगर मुझे शुरुआत से सही तरीके से बताया गया था, तो भ्रम कभी अस्तित्व में नहीं होता। – Josh

2

यह ++ निम्नलिखित कार्यों प्रदर्शन निम्नलिखित परिचालन:

  1. वृद्धि यह
  2. वापसी यह

क्योंकि यह ++ एक कॉपी बन जाती है, यह "धीमे" होने के लिए कहा जा सकता है। हालांकि, किसी भी सभ्य संकलक सबसे परिभाषित प्रकारों के लिए इस अंतर को अनुकूलित करेंगे। कुछ उपयोगकर्ता परिभाषित प्रकारों के लिए यह तेज हो सकता है।

+0

क्या आपका मतलब "धीमा" था? – Gobe

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