2010-02-11 4 views
11

मुझे कहीं पढ़ना याद है कि पूर्ण या छोटे के बजाय लूप काउंटर चर के रूप में पूर्णांक का उपयोग करना बेहतर है। यदि हां, क्यों? क्या यह कोई अनुकूलन लाभ प्रदान करता है?क्या लूप काउंटर चर के रूप में पूर्णांक का उपयोग करना बेहतर है?

उत्तर

14

आम तौर पर, संकलक int आपके सीपीयू के सामान्य प्रयोजन रजिस्टरों में से किसी एक को डालने के लिए एक अच्छा आकार बनाने के लिए बना देगा। यह आम तौर पर तेजी से पहुंच की ओर जाता है।

बेशक कुछ भी गारंटी नहीं है। कंपाइलर कई चीजों को करने के लिए स्वतंत्र है, जिसमें मुझे लगता है कि, आपके कुछ कोड को बढ़ावा दें जो char का उपयोग कुछ बड़े प्रकार के लिए करते हैं। तो अंतर भी कोई फर्क नहीं पड़ता।

वास्तव में, जवाब है कि अपने संकलक के लिए सच है के लिए, आप विधानसभा यह आउटपुट पर गौर करना चाहिए।

+0

आप सही हैं, लेकिन कई 8-बिट माइक्रोकंट्रोलर (पीसी और सर्वर से अधिक एक साथ) हैं, जो एक ही रजिस्टर में int को फिट नहीं कर सकते हैं। शायद एक 'uint8_fast_t' प्रदर्शन – 12431234123412341234123

8

32-बिट आर्किटेक्चर ऑपरेशंस में 4 बाइट्स (int) चर के साथ आमतौर पर तेज़ होते हैं। यह मुख्य रूप से रजिस्टरों और मेमोरी संरेखण के आकार के कारण होता है। 64 बिट आर्किटेक्चर में यह int (स्वचालित) स्वचालित रूप से 64-बिट पूर्णांक बनाया जाएगा।

3

int प्रकार आमतौर पर आपके प्लेटफ़ॉर्म पर सबसे तेज़ कार्यान्वित पूर्णांक प्रकार होने की उम्मीद की जा सकती है, और इसलिए डिफ़ॉल्ट विकल्प होना चाहिए।

से & आर, दूसरा संस्करण, पी। 36:

int: एक पूर्णांक, आमतौर पर होस्ट मशीन पर पूर्णांक के प्राकृतिक आकार को दर्शाता है।

+0

आह, गलत गलतीकरण की तरह कुछ भी नहीं। आप पूर्णांक का उपयोग करके अनुवांशिक कार्यों को कार्यान्वित कर सकते हैं, फ्लोटिंग पॉइंट प्रोसेसर के साथ फ्लोट के रूप में तेज़ नहीं होंगे। इसके अलावा, इनट्स की एक सरणी जहां सरणी में मान एक फिट फिट होगा, मेमोरी बैंडविड्थ को चार बार प्रोसेस करने की आवश्यकता होगी। – Skizz

+0

ने "सबसे तेज़ कार्यान्वित पूर्णांक प्रकार" में बदल दिया। –

2

लूप काउंटर के लिए size_t प्रकार का उपयोग करना बेहतर होगा। यह 64 बिट्स तक स्केल करेगा।

+1

एक लूप है जो 2^64-1 मुझे डराता है: डी –

+0

आपको 0 से शुरू करने और सबसे बड़े संभव मूल्य में समाप्त होने की आवश्यकता नहीं है xD – fortran

+0

हम आमतौर पर 2 से ऊपर चलाएंगे^आने वाले सालों में 31-1। यह बहुत बेहतर है कि इसके लिए हमारा कोड तैयार किया गया है। –

1

कुछ मामलों में, char एस (या यहां तक ​​कि short एस) के साथ अतिप्रवाह समस्याएं गैर-टर्मिनिंग लूप का उत्पादन करती हैं।

4

एलेक्सी * सही है, यह एक प्रकार वास्तुकला के रूप में एक ही चौड़ाई (यानी एक 32 बिट सिस्टम के लिए एक int32) है कि

इसके अलावा, अगर आप

for(char i=0;i<max;++i) 
यानी एक चार का उपयोग का उपयोग करने के आम तौर पर तेज है

वहाँ एक मामूली मौका है कि आप (या एक सहयोगी) कुछ उच्च करने के लिए एक महीने का समय और परिवर्तन अधिकतम में कोड करने के लिए वापस आ जाएगा, एक अतिप्रवाह और एक कष्टप्रद बग के कारण है;)

सैम

* और हर कोई जिसने उत्तर दिया था, जबकि मैं इसे लिख रहा था!

2

कभी ध्यान दें कि सी मानक किस आकार के पूर्णांक के बारे में iffy है? यह तथ्य डिवाइस चालक इंजीनियरों और संचार प्रोटोकॉल पर काम करने वाले लोगों को एक चिड़चिड़ाहट में चलाता है क्योंकि उनका मानना ​​है कि भाषा को वस्तुओं के आकार को स्पष्ट रूप से परिभाषित करना चाहिए।

सी कहता है कि int कार्यान्वयन आर्किटेक्चर के लिए प्राकृतिक आकार है। इसका मतलब है कि इसे कम से कम किसी अन्य आकार के रूप में कुशलता से संभाला जाएगा। X86 आर्किटेक्चर लें: 32-बिट प्रोग्राम में उपयोग किए गए short (16 बिट पूर्णांक) में अतिरिक्त "आकार ओवरराइड" संशोधन करने वाले निर्देश होते हैं। तो कोड में अधिक बाइट्स हैं, हालांकि आमतौर पर कोई प्रदर्शन जुर्माना नहीं होता है।जब तक अतिरिक्त बाइट्स कैश लाइन ओवरफ़्लो न हो ....

char काउंटर के लिए x86 जेनरेट कोड आमतौर पर वृद्धि के बाद मास्किंग शामिल करता है यह सुनिश्चित करने के लिए कि यह 8 बिट्स रहता है। ऐसा लगता है कि एक छोटे चर का उपयोग छोटे और कड़े हो जाएगा, लेकिन यह x86, और कई अन्य सामान्य CPUs का मामला नहीं है।

1

यह वास्तव में उस मंच पर निर्भर करता है जिसे आप कोड के लिए लिख रहे हैं। उपयोग करने का सबसे अच्छा तरीका यह है कि इसे अपने प्लेटफ़ॉर्म से मिलान करें। हां, यदि आप एक साधारण 8 बिट माइक्रो के लिए कोड लिख रहे हैं, तो शायद uint8_t का उपयोग करना uint16_t का उपयोग करने से बेहतर है।

2

इस सामान के बारे में चिंता करने से पहले अपने लूप को ठीक करने के बारे में चिंता करें। int, char या short के बीच लूप काउंटर के प्रकार को बदलकर गति या कोड आकार में मापने योग्य अंतर की तुलना में आपके लूप सीमाओं में एक-एक-एक त्रुटि होने की संभावना अधिक है। तो पहले शुद्धता के बारे में चिंता करें।

कहा कि, int या unsigned int का उपयोग कर जब तक आप अन्यथा करने के लिए कारण है के लिए डिफ़ॉल्ट - लेकिन मैं यह कहना है क्योंकि आप कम अतिप्रवाह के बारे में चिंता या बड़ा प्रकार के साथ चारों ओर लपेट नहीं है क्योंकि यह तेजी से हो सकता है करने के लिए आवश्यकता होती है (भले ही यह हो सकता है)।

0

यह वास्तव में आपके लूप क्या कर रहा है इस पर निर्भर करता है। उदाहरण के लिए इस लूप को लें:

typedef struct _SomeData 
{ 
    /* some data here */ 
} SomeData; 

void SomeFunction (SomeData *array_of_data, int number_of_elements) 
{ 
    int i; 

    for (i = 0 ; i < number_of_elements ; ++i) 
    { 
    DoSomethingWithData (&array_of_data [i]); 
    } 
} 

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

void SomeFunction (SomeData *array_of_data, int number_of_elements) 
{ 
    SomeData *current = array_of_data, *end = &array_of_data [number_of_elements]; 

    while (current < end) 
    { 
    DoSomethingWithData (current++); 
    } 
} 

जो सभी पर पूर्णांकों का उपयोग नहीं करता है और अधिक संकलक की परवाह किए बिना अच्छा उत्पादन उत्पन्न करने के लिए (आधुनिक compilers ऊपर की तरह कुछ करने के लिए पूर्णांक संस्करण का अनुकूलन करने की संभावना है की संभावना है वैसे भी)।

तो, लूप के लिए पूर्णांक हमेशा आवश्यक नहीं होते हैं, और सर्वोत्तम अनुकूलन हमेशा ऐसा कुछ नहीं करना है जो आवश्यक नहीं है। यदि, हालांकि, लूप को स्पष्ट रूप से पूर्णांक की आवश्यकता होती है तो int प्रकार आमतौर पर सर्वोत्तम परिणाम प्रदान करेगा।

बेशक, आपको कोड के प्रदर्शन के बारे में सुनिश्चित करने के लिए हमेशा एक प्रोफाइलर का उपयोग करना चाहिए और इस प्रकार के प्रकार को बदलने से कोई फर्क नहीं पड़ता है।

1

आमतौर पर, int लूपिंग के लिए सही विकल्प है। ऐसा होने के दो कारण नहीं हो सकते हैं:

  1. यह आवश्यक से बड़ा हो सकता है। SDCC Z80 जैसे कुछ 8 बिट प्रोसेसर का समर्थन करता है, जो रजिस्टरों को 8 बिट एक्सेस की अनुमति देता है, हालांकि आकार (int) = 2। यदि आपको अपने लूप वैरिएबल के लिए 8 से अधिक बिट्स की आवश्यकता नहीं है, तो आकार (char) = 1 के साथ वर्णों का उपयोग करके, ऑप्टिमाइज़र को पंजीकरण स्थान में अधिक क्रैक करने की अनुमति मिलती है, जिसके परिणामस्वरूप तेज़ कोड होता है।
  2. यह बहुत छोटा हो सकता है। यदि चींटियां 16 बिट्स हैं, तो आपके पास लूप हो सकते हैं जो कई बार से अधिक चलते हैं।

तो, हाँ, आपको अपने आर्किटेक्चर के आधार पर कितनी बड़ी चींटियां हैं, इस बारे में सोचना पड़ सकता है। लेकिन आमतौर पर आप नहीं करते हैं।