2010-05-12 11 views
17

Let कहते हैं कि मैंक्या स्विच स्टेटमेंट में केस का ऑर्डर प्रदर्शन में भिन्न हो सकता है?

switch(alphabet) { 

    case "f": 
     //do something 
     break; 

    case "c": 
     //do something 
     break; 

    case "a": 
     //do something 
     break; 

    case "e": 
     //do something 
     break; 

} 

नीचे के रूप में एक स्विच बयान है अब मुझे पता है कि Alphabet ई होने की आवृत्ति उच्चतम एक, सी और एफ द्वारा क्रमशः पीछा किया जाता है लगता है। तो, मैं तो बस case बयान आदेश पुनर्गठन और इस प्रकार उन्हें बनाया:

switch(alphabet) { 

    case "e": 
     //do something 
     break; 

    case "a": 
     //do something 
     break; 

    case "c": 
     //do something 
     break; 

    case "f": 
     //do something 
     break; 
} 

दूसरा switch बयान पहले switch बयान की तुलना में तेजी हो जाएगा? यदि हां और यदि मेरे कार्यक्रम में मुझे इस switch कथन को कई बार कॉल करने की आवश्यकता है, तो क्या यह काफी सुधार होगा? या यदि प्रदर्शन में सुधार करने के लिए मैं अपने आवृत्ति ज्ञान का उपयोग कैसे कर सकता हूं?

+3

क्या आपको यह जानने का सबसे स्पष्ट तरीका नहीं पता होना चाहिए कि वास्तविक दुनिया परिदृश्यों के साथ प्रोफाइल कैसे करें और अनुकूलित करें जहां आपको इसकी आवश्यकता है? –

उत्तर

20

इतना नहीं कि आपको चिंतित होना चाहिए। यह निश्चित रूप से ऐसा कुछ नहीं है जिसे भविष्यवाणी की जा सकती है।

स्ट्रिंग केस लेबल के साथ, कंपाइलर वास्तव में एक आंतरिक हैश तालिका का उपयोग करता है जो स्ट्रिंग को जंप-टेबल में इंडेक्स में मैप करता है। तो ऑपरेशन वास्तव में ओ (1) है - लेबल की संख्या से स्वतंत्र।

पूर्णांक लेबल के लिए, तो मेरा मानना ​​है कि जेनरेट किया गया वास्तविक कोड लेबल की संख्या और संख्या लगातार (या "लगभग" लगातार) पर निर्भर करता है। यदि वे लगातार हैं (1, 2, 3, 4, ...) तो वे सिर्फ एक जंप टेबल में बदल जाएंगे। यदि उनमें से बहुत सारे हैं, तो हैशटेबल + कूद तालिका (तारों के साथ) का उपयोग किया जाएगा। यदि केवल कुछ लेबल हैं और वे तुरंत एक जंप टेबल में परिवर्तित होने के लिए टेबल नहीं हैं, तो केवल तभी को ....इस वक्तव्यों की एक श्रृंखला में बदल दिया जाएगा।

सामान्य रूप से, आपको कोड लिखना चाहिए ताकि आप इसे पढ़ सकें, ताकि संकलक "तेज़" कोड उत्पन्न कर सके।

(नोट मेरी वर्णन ऊपर कैसे सी # संकलक आंतरिक रूप से काम करता है के एक कार्यान्वयन विस्तार है: आप इसे हमेशा कि तरह काम पर भरोसा नहीं करना चाहिए - वास्तव में, यह और भी वास्तव में अब है कि की तरह काम नहीं कर सकते , लेकिन कम से कम यह सामान्य विचार है)।

+0

+1: बस मैं क्या कहने जा रहा था। इन्हें गोटो के रूप में कार्यान्वित किया जाता है (सत्यापित करने के लिए चेक परावर्तक)। यह ओ (1) है - आपको वास्तव में उस बिंदु पर अनुकूलित करने की चिंता नहीं करनी चाहिए ... – Khanzor

+2

सभी -1 के साथ क्या है? मेरे द्वारा –

+3

+1। यदि perf ** वास्तव में ** एक मुद्दा है, तो धातु के करीब बैठने वाली भाषा का उपयोग करने पर विचार करें। –

-1

मुझे लगता है कि स्विच केस करने का तरीका यह है कि यह कुछ मैच खोजने के लिए सभी मामलों में ऊपर से नीचे तक लूप करेगा। यदि यह मेल खाता है, तो यह वहां रुक जाता है।

तो, यदि आपने आवृत्ति मामलों को प्राथमिकता देने के लिए परिवर्तन किए हैं, तो उत्तर हाँ है, यह किसी भी तरह प्रदर्शन के साथ मदद कर सकता है। लेकिन मेरा मानना ​​है कि इससे ज्यादा मदद नहीं मिलेगी।

1

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

लेकिन यदि केस मान बहुत अधिक हैं, तो यह एक सुरक्षित शर्त है कि वे ifelse if पर खराब हो जाएंगे, इसलिए शीर्ष पर अपना केस 'ई' डालना निश्चित रूप से चीजों को गति देगा।

यह सी # में भी applicable है, सी # केवल छोटे मूल्यों के साथ स्विच स्टेटमेंट्स के लिए एक जंप टेबल भी बनाता है, यद्यपि केवल आसन्न मूल्यों के लिए। तो यह ओ (1) है, यदि कोई भी मान मेल नहीं खाता है तो भी कोई परीक्षण नहीं होता है।

2

यह इस बात पर निर्भर करता है कि कंपाइलर स्विच स्टेटमेंट को कैसे लागू करता है।

सबसे पहले, आप मनमाने ढंग से आदेश की अनुमति नहीं दे सकते; यदि आपके पास एक सी-जैसी भाषा (सी, सी ++, सी #, जावा, ...) में एक केस ब्लॉक है, और उस केस ब्लॉक ब्रेक में समाप्त नहीं होता है, तो आप मामलों को पुनर्व्यवस्थित नहीं कर सकते क्योंकि की अनुपस्थिति ब्रेक का मतलब है कि संकलक को अगले मामले में गिरावट को लागू करना होगा। अगर हम इस विशेष स्थिति को अनदेखा करते हैं, तो आप शेष मामलों की अनुमति दे सकते हैं।

यदि मामलों की संख्या छोटी है, तो संकलक तुलना के अनुक्रमों द्वारा केस परीक्षण लागू कर सकता है। यदि मामलों की संख्या मामूली है, तो यह मामलों से संतुलित बाइनरी पेड़ का निर्माण कर सकती है। यदि मामलों की संख्या बड़ी है, तो अधिकांश कंपाइलर स्विच मान पर अनुक्रमित शाखा को कार्यान्वित करते हैं यदि यह से एक घना सेट है। यदि केस मानों के सेट के हिस्से घने हैं, और भागों नहीं हैं, तो संकलक बाँध के पेड़ का उपयोग करके समूहों को समूहों में विभाजित कर सकता है ताकि घने सेट के बीच और घने सेट के भीतर एक अनुक्रमित कूद का चयन किया जा सके। (वास्तव में, संकलक तकनीकी रूप से ऐसा कुछ भी कर सकता है जो उचित मामले पर नियंत्रण पास करता है, लेकिन अक्सर यह उपर्युक्त में से एक है)।

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

+1

स्पष्टता के लिए, प्रश्न सी # टैग किया गया है, और सी # यहां पहले अनुच्छेद में वर्णित मामलों के माध्यम से गिरावट का समर्थन नहीं करता है (प्रत्येक मामले में 'ब्रेक' या 'रिटर्न'' के साथ समाप्त किया जाना चाहिए। – Dusty

+0

दिलचस्प। तो लोग अनावश्यक रूप से सी # में "ब्रेक" कोडिंग कर रहे हैं (उदाहरण के लिए ओपी का उदाहरण देखें)। वास्तव में मेरा जवाब बहुत ज्यादा नहीं बदलता है। –

+0

नहीं, सी # इस मामले में थोड़ा वर्बोज़ है, आपको स्पष्ट रूप से केस ब्लॉक को समाप्त करना होगा; 'ब्रेक' (या 'रिटर्न') की आवश्यकता है (संभावित रूप से फॉल-थ्रू मामलों के खिलाफ एक ब्रेकिंग बदलाव बनने के लिए सुरक्षा के लिए उन्हें भविष्य में लागू किया जाना चाहिए)। और मैं सहमत हूं, आपका उत्तर अभी भी सही और उपयोगी है। – Dusty

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