c++ - क्या()और जबकि()के बीच कोई प्रदर्शन अंतर है?




performance for-loop while-loop (14)

नहीं। अगर वे समकक्ष चीजें कर रहे हैं, तो वे उसी कोड को संकलित करेंगे - जैसा कि आप कहते हैं, यह अर्थशास्त्र के बारे में है। वह चुनें जो सबसे अच्छा प्रतिनिधित्व करता है जिसे आप व्यक्त करने की कोशिश कर रहे हैं।

या यह सब अर्थशास्त्र के बारे में है?


while() तेजी से / धीमे for() धीमा है? आइए ऑप्टिमाइज़ेशन के बारे में कुछ चीजों की समीक्षा करें:

  • कंपाइलर-लेखक कूदते, तुलना, वृद्धि, और उनके द्वारा उत्पन्न अन्य प्रकार के निर्देशों के लिए कम कॉल करके चक्रों को दाढ़ी देने के लिए बहुत मेहनत करते हैं।

  • दूसरी तरफ कॉल निर्देश, कई चक्रों को अधिक चक्रों का उपभोग करते हैं, लेकिन संकलक उनको हटाने के लिए कुछ भी करने के लिए लगभग शक्तिहीन है।

  • प्रोग्रामर के रूप में, हम बहुत सारे फ़ंक्शन कॉल लिखते हैं, कुछ क्योंकि हमारा मतलब है, कुछ क्योंकि हम आलसी हैं, और कुछ क्योंकि संकलक उन्हें बिना स्पष्ट किए फिसलता है।

  • अधिकांश समय, इससे कोई फर्क नहीं पड़ता, क्योंकि हार्डवेयर इतना तेज है, और हमारी नौकरियां इतनी छोटी हैं कि कंप्यूटर एक बीगल कुत्ते की तरह है जो उसके भोजन को भेड़िये और अधिक मांगता है।

  • कभी-कभी, हालांकि, नौकरी काफी बड़ी है कि प्रदर्शन एक मुद्दा है।

  • तो फिर हम क्या करें? बड़ा भुगतान कहां है?

    • लूपों से कुछ चक्रों को दाढ़ी देने के लिए कंपाइलर प्राप्त करना और ऐसा?
    • फंक्शन कॉल ढूंढना जो वास्तव में नहीं किया जाना चाहिए?
  • कंपाइलर बाद वाले नहीं कर सकता है। केवल हम प्रोग्रामर कर सकते हैं।

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

  • प्रोफाइलर एक शुरुआत है। मैं यह करता हूँ।

जब विली सटन ने पूछा कि आप बैंकों को क्यों लूटते हैं तो अपोक्राफल उद्धरण ? :
क्योंकि वह जगह है जहां पैसा है।

यदि आप चक्रों को सहेजना चाहते हैं, तो पता लगाएं कि वे कहां हैं।


while लूप के परीक्षण में चर के दायरे के for लूप के शीर्षलेख में घोषित चर के दायरे से अधिक व्यापक है।

इसलिए, यदि परिवर्तनीय जीवित लंबे समय तक रखने के दुष्प्रभाव के रूप में प्रदर्शन प्रभाव हैं, तो थोड़ी देर के बीच चुनने के लिए प्रदर्शन प्रभाव होंगे और लूप के लिए चुनने में प्रदर्शन प्रभाव होंगे (और इसके दायरे को कम करने के लिए {} में थोड़ी देर लपेटना नहीं होगा चर )।

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


लूप अनोलिंग का उपयोग कर अनुकूलित करने वाले कंपाइलर्स शायद फॉर-लूप केस में ऐसा ही करेंगे।


Atmel ATMega पर () () के लिए तेज है। AVR035 में यह क्यों समझाया गया है: एवीआर के लिए कुशल सी कोडिंग।

सवाल में पीएस मूल मंच का उल्लेख नहीं किया गया था।


मैं कंपाइलर लिखता हूँ। हम सशर्त और बिना शर्त शाखाओं में सभी "संरचित" नियंत्रण प्रवाह ( if , while , के for , switch , do ...) को संकलित करते हैं। फिर हम नियंत्रण-प्रवाह ग्राफ का विश्लेषण करते हैं। चूंकि एक सी कंपाइलर को सामान्य goto किसी भी तरह से निपटना पड़ता है, इसलिए सब कुछ शाखा और सशर्त शाखा निर्देशों को कम करना सबसे आसान है, फिर उस मामले को अच्छी तरह से संभालना सुनिश्चित करें। (एसी कंपाइलर को सिर्फ हस्तलिखित कोड पर ही नहीं बल्कि स्वचालित रूप से जेनरेट किए गए कोड पर भी अच्छा काम करना पड़ता है, जिसमें कई, कई goto स्टेटमेंट हो सकते हैं।)


जारी रखें और इसके दौरान अलग-अलग व्यवहार करें: इसके लिए , यह काउंटर बदलता है, जबकि , आमतौर पर यह नहीं होता है


कोई अर्थपूर्ण अंतर नहीं है, किसी भी संकलित अंतर की आवश्यकता नहीं है। लेकिन यह संकलक पर निर्भर करता है। इसलिए मैंने जी ++ 4.3.2, सीसी 5.5, और एक्सएलसी 6 के साथ प्रयास किया।

जी ++, सीसी समान थे, एक्सएलसी नहीं था

एक्सएलसी में अंतर प्रारंभिक पाश प्रविष्टि में था।

extern int doit( int );
void loop1( ) {
  for ( int ii = 0; ii < 10; ii++ ) {
    doit( ii );
  }
}

void loop2() {
  int ii = 0; 
  while ( ii < 10 ) {
    doit( ii );
    ii++;
  }
}

एक्सएलसी आउटपुट

.loop2:                                 # 0x00000000 (H.10.NO_SYMBOL)
    mfspr   r0,LR
    stu     SP,-80(SP)
    st      r0,88(SP)
    cal     r3,0(r0)
    st      r3,64(SP)
    l       r3,64(SP)  ### DIFFERENCE ###
    cmpi    0,r3,10
    bc      BO_IF_NOT,CR0_LT,__L40
...
enter code here
.loop1:                                 # 0x0000006c (H.10.NO_SYMBOL+0x6c)
    mfspr   r0,LR
    stu     SP,-80(SP)
    st      r0,88(SP)
    cal     r3,0(r0)
    cmpi    0,r3,10    ### DIFFERENCE ###
    st      r3,64(SP)
    bc      BO_IF_NOT,CR0_LT,__La8
...

शायद केवल कोडिंग शैली।

  • यदि आप पुनरावृत्तियों की संख्या जानते हैं।
  • जबकि अगर आप पुनरावृत्तियों की संख्या नहीं जानते हैं।

यदि आपके लिए और लूप एक ही चीज करते हैं, तो कंपाइलर द्वारा उत्पन्न मशीन कोड (लगभग) होना चाहिए।

उदाहरण के लिए कुछ परीक्षणों में मैंने कुछ साल पहले किया था,

for (int i = 0; i < 10; i++)
{
...
}

तथा

int i = 0;
do
{
  ...
  i++;
}
while (i < 10);

एक ही जेएमपी के साथ बिल्कुल वही कोड उत्पन्न करेगा, या (और नील टिप्पणियों में इंगित किया जाएगा), जो चिंता करने के लिए प्रदर्शन में काफी बड़ा अंतर नहीं देगा।


संक्षिप्त उत्तर: नहीं, वे बिल्कुल वही हैं।

मान लीजिए सिद्धांत में यह संकलक पर निर्भर हो सकता है; वास्तव में टूटा हुआ कुछ थोड़ा अलग कर सकता है लेकिन मुझे आश्चर्य होगा।

बस मज़े के लिए यहां दो प्रकार हैं जो x86 gcc संस्करण 4.3.3 का उपयोग करते हुए मेरे लिए एक ही असेंबली कोड को संकलित करते हैं जैसा कि उबंटू के साथ भेज दिया गया है। आप linux पर objdump साथ अंतिम बाइनरी पर उत्पादित असेंबली की जांच कर सकते हैं।

int main()
{
#if 1
    int i = 10;
    do { printf("%d\n", i); } while(--i);
#else
    int i = 10;
    for (; i; --i) printf("%d\n", i);
#endif
}

संपादित करें: यहां "संतरे के संतरे" हैं जबकि लूप उदाहरण भी एक ही चीज़ पर संकलित होता है:

    while(i) { printf("%d\n", i); --i; }

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


दोनों बराबर हैं। यह अर्थशास्त्र का मामला है।

केवल अंतर ही काम में पड़ सकता है ... निर्माण करते समय, जहां आपने शरीर के बाद तक स्थिति के मूल्यांकन को स्थगित कर दिया, और इस प्रकार 1 मूल्यांकन बचा सकता है।

i = 1; do { ... i--; } while( i > 0 ); 

विरोध के रूप में

for(  i = 1; i > 0; --i )
{ ....
}  

इन तरीकों के बीच अंतर हैं, आप पैरामीटर को कैसे पास करना चाहते हैं।

"ए के लिए सरणी और सी के लिए सी" एक आसान निमोनिक है।







c++ c performance for-loop while-loop