2015-10-19 7 views
5

अगर मैं इस तरह पाश हालत के लिए समारोह कॉल में है:लूप स्थिति के लिए फंक्शन कॉल?

for (auto it = s.begin(); it != s.end(), ++it) {} 

यह प्रत्येक यात्रा पर कहा जाता है? मुझे उम्मीद है कि हाँ। क्या संकलक इसे अनुकूलित करने की अनुमति देता है? क्या मौजूदा कंपाइलर्स ऐसा करने के लिए पर्याप्त स्मार्ट हैं? या मैं बेहतर कुछ निम्नलिखित का उपयोग कर रहा हूं:

for (auto it = s.begin(), auto end = s.end(); it != end; ++it) {} 

?

+0

जैसा कि आप सी ++ 11 का उपयोग कर रहे हैं, इस मुद्दे से बचने वाले लूप के लिए श्रेणी-आधारित का उपयोग करने पर विचार करें। –

+0

@NeilKirk मेरे मामले में उपयोग करने योग्य नहीं है, मुझे वास्तव में मज़ेदार सामान करने के लिए पुनरावर्तक की आवश्यकता है। – Paladin

+1

व्यक्तिगत रूप से मैं अपने दूसरे दृष्टिकोण का उपयोग करके अपने लूप लिखता हूं, तो मुझे इसके बारे में चिंता करने की ज़रूरत नहीं है। मुझे नहीं पता कि यह कितना दूर है या अभ्यास में नहीं है। –

उत्तर

4

हां, कार्यक्रम को प्रत्येक पुनरावृत्ति पर दूसरी अभिव्यक्ति it != s.end() पर कॉल करना होगा। मुझे लगता है कि संकलक कुछ निश्चित स्थिति में इसे अनुकूलित कर सकता है।

वैसे भी, कंपाइलर का काम न करें। यदि इसे अनुकूलित किया जा सकता है, तो संकलक पहले से ही ऐसा करने का एक शानदार मौका है, और फिर भी इस कॉल में कोई महत्वपूर्ण प्रदर्शन हिट नहीं है।

for (auto& i : s) { 
    // instructions 
} 

इस तरह से, संकलक अपने कोड का अनुकूलन करने के लिए और भी अधिक अवसर है और इसे पढ़ने के लिए आसान है:

अपने मामले अनुमति हैं, तो आप एक सीमा पाश के लिए आधारित का उपयोग करना चाहिए।

यदि आप कुछ उदाहरण चाहते हैं कि कंपाइलर सामान को अनुकूलित कैसे कर सकता है, तो इसे देखो! http://ridiculousfish.com/blog/posts/will-it-optimize.html

+0

मैं आमतौर पर इसका उपयोग करता हूं, लेकिन मुझे वास्तव में इटरेटर को थोड़ा सा उपयोग करने की ज़रूरत है, इसलिए क्लासिक फोरैच लूप मेरे लिए काम नहीं करेगा – Paladin

+0

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

+0

मैंने अपना उत्तर अधिक सामान्य होने के लिए संपादित किया और मैंने अभी एक महान लेख के लिए एक लिंक जोड़ा है। –

6

for (auto it = s.begin(); it != s.end(), ++it) 

s.begin() में केवल एक बार कहा जाता है।
s.end() और operator++() (++it के लिए) लूप के प्रत्येक पुनरावृत्ति में बुलाए जाते हैं।

क्या संकलक इसे अनुकूलित करने की अनुमति देता है?

कंपाइलर संकलक, कार्यान्वयन और अनुकूलन स्तर के आधार पर s.end() पर कॉल को अनुकूलित कर सकता है। मुझे आश्चर्य होगा अगर यह operator++() कॉल को अनुकूलित कर सकता है।

वर्तमान कंप्यूटर्स ऐसा करने के लिए पर्याप्त स्मार्ट हैं?

इसका उत्तर नहीं दे सकता।

या मैं बेहतर निम्नलिखित की तरह कुछ का उपयोग कर रहा:

for (auto it = s.begin(), auto end = s.end(); it != end; ++it) {} 

यह चोट नहीं होगा। हालांकि, यह एक समस्या हो सकती है यदि s लूप में संशोधित किया गया है। यदि s लूप में संशोधित नहीं है, तो मैं इस दृष्टिकोण का उपयोग करने की सलाह दूंगा।

1

हां, यह औपचारिक रूप से प्रत्येक पुनरावृत्ति पर बुलाया जाता है। और हां, वर्तमान कंपाइलर्स फ़ंक्शन को इनलाइन कर देंगे और देखेंगे कि s.end() प्रत्येक बार एक ही मान (पॉइंटर?) देता है।

कोड को जटिल करने की कोई आवश्यकता नहीं है, जब तक कि प्रोफाइलिंग से पता चलता है कि यह आपके प्रोग्राम में एक बाधा है (बेहद असंभव)।

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