2010-02-12 15 views
8

में int घोषित करना कुछ समय में सी ++ का उपयोग नहीं किया है। मैं अनुकूलन करने के लिए अपने जावा कंपाइलर के आधार पर रहा हूं।सी ++ लूप

सी ++ में लूप के लिए सबसे अनुकूलित तरीका क्या है? या यह मॉडरम कंपाइलर्स के साथ अब सब कुछ है? 'पुराने दिनों' में एक अंतर था।

for (int i=1; i<=100; i++) 

या

int i; 
for (i=1; i<=100; i++) 

या

int i = 1; 
for (; i<=100; i++) 

यह सी में एक ही है?

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

+6

इस तरह का सवाल वास्तव में एक बुरा संकेत है ... –

+0

+1 यह पूछने के लिए, बस मिथक को – Andres

उत्तर

12

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

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

+2

डिबफ किया जा सकता है आपके संपादन के संबंध में, यह संकलक पर निर्भर करता है। मैंने कम से कम एक कंपाइलर (एमएसवीसी ++ 6.0) देखा है जहां लूप समाप्त होने के बाद चर मौजूद नहीं है। –

+2

@ जेफ मानक अनुपालन संकलक _i_ के लिए लूप के दायरे को प्रतिबंधित करेंगे, लेकिन पुराने कंपाइलर हैं - जैसे MSVC++ 6.0 - जो नहीं। इसलिए, यदि आप पुराने कंपाइलर का उपयोग कर रहे हैं, तो यह देखने के लिए कुछ है। भाषा मानक के अनुसार, हालांकि, गुंजाइश के लिए दायरा प्रतिबंधित है। हाल के कंपाइलर्स को उस संबंध में सही तरीके से व्यवहार करना चाहिए। –

+0

एमएसवीसी पर, हैक "#define अगर (0) {} के लिए" सही व्यवहार पाने के लिए इस्तेमाल किया जा सकता है। आह हाँ, अच्छे पुराने दिन ... –

4

यह वही है। कंपाइलर इन्हें एक ही चीज़ पर अनुकूलित करेगा।

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

3

यह गति की अवधि में समान है। यदि आपके पास बाद में उपयोग नहीं है तो कंपाइलर अनुकूलित होगा।

शैली के संदर्भ में - मैं परिभाषा को लूप निर्माण में डाल दूंगा, क्योंकि इससे आप जोखिम को कम कर देते हैं यदि आप बाद में किसी अन्य को परिभाषित करते हैं तो आप संघर्ष करेंगे।

9

अंतर अंतर है।

for(int i = 1; i <= 100; ++i) 

क्योंकि तब मैं के दायरे पाश के लिए के लिए प्रतिबंधित है आम तौर पर बेहतर है। यदि आप लूप के पहले इसे घोषित करते हैं, तो लूप समाप्त हो जाने के बाद यह मौजूद रहता है और अन्य चर के साथ संघर्ष कर सकता है। यदि आप केवल लूप में इसका उपयोग कर रहे हैं, तो इसके अलावा इसे लंबे समय तक रहने का कोई कारण नहीं है।

+0

कुछ पुराने कंपाइलरों में, मैं का दायरा, समारोह के अंत में है। int को ले जाने से, लूप के बाहर आपको अन्य कंपाइलर्स के साथ अच्छा रहता है। – EvilTeach

+0

@EvilTech केवल पुराने, गैर-अनुपालन वाले कंपाइलर्स को यह समस्या होगी। इसलिए, जब तक आपको लगता है कि ऐसा कोई अच्छा मौका नहीं है कि आपके कोड का उपयोग ऐसे कंपाइलर के साथ किया जाएगा, तो मैं इसके बारे में चिंता नहीं करता। यदि यह एक समस्या है, तो लूप के चारों ओर ब्रेसिज़ की एक अतिरिक्त जोड़ी डालने से समस्या ठीक हो जाएगी। –

1

माइक्रो-ऑप्टिमाइज़ेशन के बारे में चिंता न करें, संकलक इसे करने दें। जो भी सबसे पठनीय है उठाओ। ध्यान दें कि for प्रारंभिक कथन के भीतर एक चर घोषित करने के लिए वेरिएबल को for कथन (सी ++ 03 § 6.5.3 1) पर स्कॉप्स किया गया है, हालांकि कंपाइलर्स का सटीक व्यवहार भिन्न हो सकता है (कुछ आपको चुनने देते हैं)। यदि लूप के बाहर कोड चर का उपयोग करता है, तो इसे लूप के बाहर घोषित करें। यदि चर लूप के लिए वास्तव में स्थानीय है, तो इसे प्रारंभकर्ता में घोषित करें।

1

यह पहले से ही उल्लेख किया गया है कि दोनों के बीच मुख्य अंतर गुंजाइश है।सुनिश्चित करें कि आप समझते हैं कि आपका संकलक घोषित किसी पूर्णांक के दायरे हैंडल के रूप में

for (int i = 1; ...;...) 

मुझे पता है कि जब MSVC++ 6 का उपयोग कर, मैं पाश बाहर दायरे में अब भी है, बस के रूप में अगर यह पाश से पहले घोषित किया गया बनाओ । यह व्यवहार VS2005 से अलग है, और मुझे जांचना होगा, लेकिन मुझे लगता है कि मैंने जीसीसी का अंतिम संस्करण इस्तेमाल किया था। उन दोनों कंपाइलरों में, वह चर केवल लूप के अंदर दायरे में था।

+0

यह वीसी ++ 6 में एक प्रसिद्ध बग है। यदि आप वास्तव में ब्रेसिज़ के दूसरे सेट के साथ लूप के चारों ओर घूमते हैं। – jmucchiello

5

मान लें कि मूल पोस्टर में एक लूप था जिसे वे वास्तव में अनुकूलित करना चाहते थे - प्रत्येक निर्देश की गणना की गई। हम कैसे अनुभव कर सकते हैं - अनुभवजन्य - उसके प्रश्न का उत्तर?

जीसीसी कम से कम एक उपयोगी है, अगर असामान्य रूप से उपयोग किया जाने वाला स्विच, '-एस'। यह .c फ़ाइल के असेंबली कोड संस्करण को डंप करता है और ओपी पॉज़ जैसे प्रश्नों के उत्तर देने के लिए इसका उपयोग किया जा सकता है। मैं एक साधारण प्रोग्राम लिखा है:

int main() 
{ 
    int sum = 0; 

    for(int i=1;i<=10;++i) 
    { 
     sum = sum + i; 
    } 
    return sum; 
} 

और भाग गया: gcc -O0 -std=c99 -S main.c, मुख्य कार्यक्रम के विधानसभा संस्करण बनाने।

movl $0, -8(%rbp) 
    movl $1, -4(%rbp) 
    jmp  .L2 
.L3: 
    movl -4(%rbp), %eax 
    addl %eax, -8(%rbp) 
    addl $1, -4(%rbp) 
.L2: 
    cmpl $10, -4(%rbp) 
    jle  .L3 

आप यह पता लगाने की क्या हो रहा है एक विधानसभा विशेषज्ञ होने की जरूरत नहीं है: यहाँ (फुज्जी के कुछ हटाया के साथ) main.s की सामग्री है। movl चाल मानता है, addl चीजें जोड़ता है, cmpl तुलना करता है और जेले 'कम से कम कूद' के लिए खड़ा है, $ स्थिरांक के लिए है। यह 0 में कुछ लोड हो रहा है - यह 'योग' होना चाहिए, 1 किसी और चीज में - आह, 'मैं'! एल 2 पर कूद जहां हम 10 की तुलना करते हैं, जोड़ने के लिए एल 3 पर जाएं। फिर से तुलना के लिए एल 2 के माध्यम से गिरना। साफ! लूप के लिए ए।

बदलें कार्यक्रम के लिए:

int main() 
{ 
    int sum = 0; 
    int i=1; 
    for(;i<=10;++i) 
    { 
     sum = sum + i; 
    } 
    return sum; 
} 

को पुन: चलाएं जीसीसी और उसके एवज में विधानसभा बहुत समान हो जाएगा। रिकॉर्डिंग लाइन नंबरों के साथ कुछ सामान चल रहा है, इसलिए वे समान नहीं होंगे, लेकिन असेंबली एक जैसी होती है। अंतिम मामले के साथ एक ही परिणाम। तो, अनुकूलन के बिना भी, कोड बस इसके बारे में है।

मज़े के लिए, अनुकूलन को सक्षम करने और .s फ़ाइल को देखने के लिए '-O0' के बजाय '-O3' के साथ जीसीसी को दोबारा शुरू करें।

main: 
movl $55, %eax 
ret 

जीसीसी केवल पता लगा नहीं हम पाश के लिए एक कर रहे थे, लेकिन यह भी महसूस किया कि यह चलाने के लिए समय की एक स्थिर संख्या संकलन समय पर हमारे लिए पाश किया था, बाहर chucked 'i' और 'योग' और जवाब को कोडित किया - 55! यह तेज़ है - हालांकि थोड़ा सा योगदान हुआ।

कहानी का नैतिक? अपना कोड साफ और अच्छी तरह से डिज़ाइन किया गया यह सुनिश्चित करने के लिए अपना समय व्यतीत करें। पठनीयता और रखरखाव के लिए कोड। पहाड़ी ओस और चीटोस पर रहने वाले लोग हमारे से अधिक चालाक हैं और हमारे लिए इन सरल अनुकूलन समस्याओं में से अधिकांश का ख्याल रखते हैं। मज़े करो!

1
for(int i = 1; i <= 100; ++i) 

एएनएसआई सी/सी 8 9 को छोड़कर यह पढ़ने के लिए सबसे आसान है, जहां यह अमान्य है।

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