एक switchकथन बनाम if/elseC # में उपयोग करने से क्या लाभ / नकारात्मक पक्ष है । मैं कल्पना नहीं कर सकता कि आपके कोड के लुक के अलावा, यह एक बड़ा अंतर है।
क्या कोई कारण है जिसके परिणामस्वरूप आईएल या संबद्ध रनटाइम प्रदर्शन मौलिक रूप से अलग होगा?
एक switchकथन बनाम if/elseC # में उपयोग करने से क्या लाभ / नकारात्मक पक्ष है । मैं कल्पना नहीं कर सकता कि आपके कोड के लुक के अलावा, यह एक बड़ा अंतर है।
क्या कोई कारण है जिसके परिणामस्वरूप आईएल या संबद्ध रनटाइम प्रदर्शन मौलिक रूप से अलग होगा?
जवाबों:
SWITCH स्टेटमेंट केवल डीबग या संगतता मोड में IFs के समान असेंबली का उत्पादन करता है। रिलीज में, इसे जंप टेबल (एमएसआईएल 'स्विच' स्टेटमेंट के माध्यम से) में संकलित किया जाएगा - जो कि ओ (1) है।
सी # (कई अन्य भाषाओं के विपरीत) भी स्ट्रिंग स्थिरांक पर स्विच करने की अनुमति देता है - और यह थोड़ा अलग तरीके से काम करता है। यह स्पष्ट रूप से मनमाना लंबाई के तारों के लिए जंप टेबल बनाने के लिए व्यावहारिक नहीं है, इसलिए अक्सर ऐसे स्विच को आईएफएस के ढेर में संकलित किया जाएगा।
लेकिन अगर ओवरहेड्स को कवर करने के लिए स्थितियों की संख्या काफी बड़ी है, तो सी # कंपाइलर एक हैशटेबल ऑब्जेक्ट बनाएगा, इसे स्ट्रिंग स्थिरांक के साथ पॉप्युलेट करेगा और कूदने के बाद उस टेबल पर एक लुकअप करेगा। हैशटेबल लुकिंग ओ (1) कड़ाई से नहीं है और इसमें लगातार लागतों पर ध्यान देने योग्य है, लेकिन यदि केस लेबल की संख्या बड़ी है, तो यह आईएफएस में प्रत्येक स्ट्रिंग निरंतर की तुलना में काफी तेज होगा।
इसे जमा करने के लिए, यदि शर्तों की संख्या 5 या अधिक से अधिक है, तो IF पर SWITCH को प्राथमिकता दें, अन्यथा जो भी बेहतर लगे उसका उपयोग करें।
सामान्य तौर पर (सभी भाषाओं और सभी संकलक को देखते हुए) एक स्विच स्टेटमेंट CAN SOMETIMES एक if / else स्टेटमेंट की तुलना में अधिक कुशल हो सकता है, क्योंकि कंपाइलर के लिए स्विच स्टेटमेंट से जंप टेबल जेनरेट करना आसान होता है। उचित बाधाओं को देखते हुए, अगर / और कथनों के लिए एक ही कार्य करना संभव है, लेकिन यह अधिक कठिन है।
C # के मामले में, यह भी सही है, लेकिन अन्य कारणों से।
बड़ी संख्या में स्ट्रिंग्स के साथ, स्विच स्टेटमेंट का उपयोग करने के लिए एक महत्वपूर्ण प्रदर्शन लाभ है, क्योंकि कंपाइलर कूद को लागू करने के लिए एक हैश तालिका का उपयोग करेगा।
कम संख्या में तार के साथ, दोनों के बीच प्रदर्शन समान है।
ऐसा इसलिए है क्योंकि उस स्थिति में C # कंपाइलर जंप टेबल उत्पन्न नहीं करता है। इसके बजाय यह MSIL उत्पन्न करता है जो IF / ELSE ब्लॉकों के बराबर है।
एक "स्विच स्टेटमेंट" MSIL निर्देश है कि जब jitted स्विच स्टेटमेंट को लागू करने के लिए जंप टेबल का उपयोग करेगा। यह केवल पूर्णांक प्रकारों के साथ काम करता है, हालांकि (यह प्रश्न तार के बारे में पूछता है)।
छोटी संख्या में तार के लिए, यह संकलक के लिए IF / ELSE ब्लॉक उत्पन्न करने के लिए अधिक कुशल है तो यह हैश तालिका का उपयोग करना है।
जब मैंने मूल रूप से इस पर ध्यान दिया, तो मैंने यह धारणा बनाई कि क्योंकि IF / ELSE ब्लॉकों का उपयोग कम संख्या में तारों के साथ किया गया था, इसलिए संकलक ने बड़ी संख्या में तारों के लिए एक ही परिवर्तन किया।
यह गलत था। 'IMA' मेरे लिए यह इंगित करने के लिए पर्याप्त था (अच्छी तरह से ... वह इसके बारे में दयालु नहीं था, लेकिन वह सही था, और मैं गलत था, जो महत्वपूर्ण हिस्सा है)
मैंने MSIL में "स्विच" निर्देश की कमी के बारे में एक हड्डी की धारणा बनाई है (मुझे लगा, अगर कोई स्विच आदिम था, तो वे हैश टेबल के साथ इसका उपयोग क्यों नहीं कर रहे थे, इसलिए एक स्विच आदिम नहीं होना चाहिए। ...)। यह मेरी ओर से गलत, और अविश्वसनीय रूप से मूर्ख दोनों था। एक बार फिर 'आईएमए' ने मेरी ओर इशारा किया।
मैंने यहां अपडेट किए क्योंकि यह उच्चतम श्रेणी का पोस्ट है, और स्वीकृत उत्तर है।
हालाँकि, मैंने इसे सामुदायिक विकी बना दिया है क्योंकि मुझे लगता है कि मैं गलत होने के लिए आरईपी के लायक नहीं हूं। अगर आपको मौका मिले, तो कृपया वोट करें 'इमा' की पोस्ट।
पसंद करने के तीन कारण switch:
मूल कोड को लक्षित करने वाला एक कंपाइलर अक्सर एक सशर्त शाखा में एक स्विच स्टेटमेंट और एक अप्रत्यक्ष कूद को संकलित कर सकता है जबकि ifएस के अनुक्रम में सशर्त शाखाओं के अनुक्रम की आवश्यकता होती है । मामलों के घनत्व के आधार पर एक बहुत से सीखे गए कागजात के बारे में लिखा गया है कि कैसे केस स्टेटमेंट को कुशलतापूर्वक संकलित किया जाए; कुछ lcc संकलक पृष्ठ से जुड़े हुए हैं । (Lcc में स्विच के लिए अधिक नवीन संकलक में से एक था।)
एक स्विच स्टेटमेंट पारस्परिक रूप से अनन्य विकल्पों में से एक विकल्प है और स्विच सिंटैक्स इस कंट्रोल फ्लो को प्रोग्रामर के लिए अधिक पारदर्शी बनाता है, फिर अगर-तब के स्टेटमेंट का एक घोंसला।
निश्चित रूप से एमएल और हास्केल सहित कुछ भाषाओं में, संकलक यह देखने के लिए जांचता है कि क्या आपने कोई केस छोड़ दिया है । मैं इस सुविधा को एमएल और हास्केल के प्रमुख लाभों में से एक के रूप में देखता हूं। मुझे नहीं पता कि C # ऐसा कर सकता है या नहीं।
एक किस्सा: एक व्याख्यान में उन्होंने जीवन भर की उपलब्धि के लिए एक पुरस्कार प्राप्त किया, मैंने टोनी होरे को यह कहते सुना कि उन्होंने अपने करियर में जो कुछ भी किया, उसमें तीन ऐसे थे जिन पर उन्हें सबसे अधिक गर्व था:
caseस्टेटमेंट कहा)मैं बिना जीने की कल्पना नहीं कर सकताswitch ।
कम्पाइलर मामूली अंतर (नथ, किसी भी?) के साथ एक ही कोड में बहुत अधिक सब कुछ अनुकूलित करने जा रहा है।
अंतर यह है कि एक स्विच स्टेटमेंट पंद्रह की तुलना में क्लीनर है यदि अन्य स्टेटमेंट एक साथ टकराते हैं।
मित्रों को मित्रों को अटकने न दें यदि-अन्यथा कथन।
दरअसल, एक स्विच स्टेटमेंट अधिक कुशल है। कंपाइलर इसे एक लुक अप टेबल पर ऑप्टिमाइज़ करेगा जहाँ से अगर / और स्टेटमेंट नहीं है। नीचे की ओर यह है कि चर मानों के साथ स्विच स्टेटमेंट का उपयोग नहीं किया जा सकता है।
आप ऐसा नहीं कर सकते:
switch(variable)
{
case someVariable
break;
default:
break;
}
इसे होना चाहिए
switch(variable)
{
case CONSTANT_VALUE;
break;
default:
break;
}
मैंने किसी और को (स्पष्ट?) बिंदु को उठाते नहीं देखा था कि स्विच स्टेटमेंट का कथित दक्षता लाभ विभिन्न मामलों पर लगभग समान रूप से होने की संभावना पर निर्भर है। उन मामलों में जहां मानों में से एक (या कुछ) बहुत अधिक होने की संभावना है, अगर-तो-और सीढ़ी बहुत तेजी से हो सकती है, यह सुनिश्चित करके कि सबसे आम मामलों की पहले जांच की जाती है:
इसलिए, उदाहरण के लिए:
if (x==0) then {
// do one thing
} else if (x==1) {
// do the other thing
} else if (x==2) {
// do the third thing
}
बनाम
switch(x) {
case 0:
// do one thing
break;
case 1:
// do the other thing
break;
case 2:
// do the third thing
break;
}
यदि x शून्य समय का 90% है, तो "if-else" कोड स्विच-आधारित कोड से दोगुना तेज़ हो सकता है। यहां तक कि अगर कंपाइलर "स्विच" को किसी प्रकार की चालाक तालिका-चालित गोटो में बदल देता है, तो यह अभी भी उतनी तेजी से नहीं होगा, जितना कि बस शून्य के लिए जांचना।
switchअसंगत हैं, तो switchकथन बेहतर है (अधिक पठनीय, कभी-कभी तेज)। यदि आप जानते हैं कि एक मामला बहुत अधिक संभावना है, तो आप उसे एक if- else- switchनिर्माण के लिए खींच सकते हैं और यदि यह औसत रूप से तेज़ है , तो आप उसे छोड़ देते हैं (दोहराएँ, यदि आवश्यक हो।) IMO जो अभी भी यथोचित पठनीय है। यदि switchपतित हो जाता है और बहुत छोटा हो जाता है, तो एक else ifरेगीक्स-रिप्ले इसे -चैन में बदलने का अधिकांश काम करेगा।
साइड विषय, लेकिन मैं अक्सर (और अधिक बार देखता हूं) if/ elseऔर के बारे में चिंता करता हूंswitch बयान बहुत सारे मामलों के साथ बहुत बड़ा हो जाता है। ये अक्सर रखरखाव को नुकसान पहुंचाते हैं।
आम दोषियों में शामिल हैं:
तै होना:
इस लिंक के अनुसार, यदि स्विच का उपयोग करके इटेरियन टेस्ट की तुलना बनाम IF स्विच , तो 1,000,000,000 पुनरावृत्तियों की तरह है, स्विच स्टेटमेंट = 43.0 द्वारा लिया गया समय और यदि स्टेटमेंट = 48.0s
जिसका शाब्दिक अर्थ 20833333 है प्रति सेकंड पुनरावृत्तियों है, इसलिए, क्या हमें वास्तव में अधिक ध्यान केंद्रित करने की आवश्यकता है,
पुनश्च: शर्तों की छोटी सूची के लिए प्रदर्शन अंतर जानने के लिए।
यदि आप बस का उपयोग कर रहे हैं या नहीं तो आधार समाधान का उपयोग कर रहे हैं? ऑपरेटर
(value == value1) ? (type1)do this : (type1)or do this;
आप या एक स्विच में दिनचर्या कर सकते हैं
switch(typeCode)
{
case TypeCode:Int32:
case TypeCode.Int64:
//dosomething here
break;
default: return;
}
यह वास्तव में आपके प्रश्न का उत्तर नहीं देता है, लेकिन यह देखते हुए कि संकलित संस्करणों के बीच थोड़ा अंतर होगा, मैं आपसे अपने कोड को इस तरह से लिखने का आग्रह करूंगा जो आपके इरादों का सबसे अच्छा वर्णन करता है। न केवल संकलक के लिए बेहतर मौका है कि आप क्या उम्मीद करते हैं, बल्कि यह दूसरों के लिए आपके कोड को बनाए रखना आसान बना देगा।
यदि आपका इरादा एक चर / विशेषता के मूल्य के आधार पर अपने कार्यक्रम को शाखा देना है, तो एक स्विच स्टेटमेंट उस इरादे को सबसे अच्छी तरह से दर्शाता है।
यदि आपका इरादा विभिन्न चर / विशेषताओं / शर्तों के आधार पर आपके कार्यक्रम को शाखा देने का है, तो एक i / और अगर श्रृंखला सबसे अच्छा उस इरादे का प्रतिनिधित्व करती है।
मैं इस बात को स्वीकार करूंगा कि लोगों को तोड़ने की आज्ञा को भूल जाने के बारे में कोडी सही है, लेकिन लगभग अक्सर मैं लोगों को जटिल करता हुआ देखता हूं अगर ब्लॉक जहां उन्हें {} गलत मिलता है, तो वे लाइनें जो सशर्त बयान में होनी चाहिए, नहीं हैं। इसका एक कारण है मैं हमेशा {} पर अपने बयानों को शामिल करता हूं, भले ही उसमें एक पंक्ति हो। न केवल पढ़ना आसान है, लेकिन अगर मुझे सशर्त में एक और पंक्ति जोड़ने की आवश्यकता है, तो मैं इसे जोड़ना नहीं भूल सकता।
ब्याज का सवाल। यह काम पर कुछ हफ्ते पहले आया था और हमने एक उदाहरण स्निपेट लिखकर और इसे .NET रिफ्लेक्टर (रिफ्लेक्टर कमाल है !! मैं इसे पसंद करता हूं) में देखकर एक उत्तर पाया।
यह वही है जो हमने खोजा है: स्ट्रिंग के अलावा किसी भी चीज़ के लिए एक मान्य स्विच स्टेटमेंट IL को एक स्विच स्टेटमेंट के रूप में संकलित किया जाता है। हालाँकि यदि यह एक स्ट्रिंग है तो इसे आईई के रूप में फिर से लिखा जाता है यदि आईएल में / अन्यथा। इसलिए हमारे मामले में हम यह जानना चाहते थे कि कैसे स्विच स्टेटमेंट स्ट्रिंग की तुलना करते हैं जैसे केस-सेंसिटिव आदि और रिफ्लेक्टर ने हमें तुरंत जवाब दे दिया। यह जानना उपयोगी था।
यदि आप स्ट्रिंग्स पर केस-संवेदी तुलना करना चाहते हैं तो आप एक स्विच स्टेटमेंट का उपयोग कर सकते हैं क्योंकि यह स्ट्रिंग का प्रदर्शन करने की तुलना में तेज़ है। if / if में एक और। (संपादित करें: क्या पढ़ें तेज है, स्ट्रिंग पर टाइप करें या कुछ और पर टाइप करें; कुछ वास्तविक प्रदर्शन परीक्षणों के लिए) हालांकि यदि आप एक केस-असंवेदनशील करना चाहते हैं, तो यह बेहतर है कि परिणामस्वरूप कोड सुंदर नहीं है।
switch (myString.ToLower())
{
// not a good solution
}
अंगूठे का सबसे अच्छा नियम स्विच स्टेटमेंट का उपयोग करना है अगर यह समझ में आता है (गंभीरता से), उदाहरण के लिए:
यदि आपको स्विच स्टेटमेंट में फीड करने के लिए वैल्यू में हेरफेर करने की आवश्यकता है (स्विच करने के लिए एक अस्थायी वेरिएबल बनाएं) तो आपको शायद एक if / अन्यथा नियंत्रण स्टेटमेंट का उपयोग करना चाहिए।
ताज़ा जानकारी:
यह वास्तव में स्ट्रिंग को अपरकेस (जैसे ToUpper()) में बदलना बेहतर है क्योंकि स्पष्ट रूप से इसमें और अधिक अनुकूलन होते हैं जो कि इन-टाइम कंपाइलर की तुलना में तब कर सकते हैं ToLower()। यह एक माइक्रो ऑप्टिमाइज़ेशन है, हालांकि एक तंग लूप में यह उपयोगी हो सकता है।
थोड़ा साइड नोट:
स्विच स्टेटमेंट की पठनीयता में सुधार के लिए निम्नलिखित प्रयास करें:
स्विच स्टेटमेंट निश्चित रूप से तेज है तो एक और यदि। स्पीडटेस्ट हैं जो ब्लैकवैप द्वारा इस पर आपूर्ति की गई हैं
http://www.blackwasp.co.uk/SpeedTestIfElseSwitch.aspx
--इसकी जांच - पड़ताल करें
लेकिन उन संभावनाओं पर बहुत अधिक निर्भर करता है जिनके लिए आप प्रयास कर रहे हैं, लेकिन जब भी संभव हो मैं एक स्विच स्टेटमेंट का उपयोग करने का प्रयास करता हूं।
न केवल सी #, बल्कि सभी सी-आधारित भाषाएं, मुझे लगता है: क्योंकि एक स्विच स्थिरांक तक सीमित है, "जंप टेबल" का उपयोग करके बहुत कुशल कोड उत्पन्न करना संभव है। C मामला वास्तव में एक अच्छा पुराना FORTRAN कंप्यूटेड GOTO है, लेकिन C # मामला अभी भी एक स्थिर के खिलाफ परीक्षण है।
ऐसा नहीं है कि ऑप्टिमाइज़र एक ही कोड बनाने में सक्षम होगा। विचार करें, उदाहरण के लिए,
if(a == 3){ //...
} else if (a == 5 || a == 7){ //...
} else {//...
}
क्योंकि वे मिश्रित बूलियन हैं, उत्पन्न कोड को एक मूल्य, और शॉर्टसर्किट की गणना करना है। अब समकक्ष पर विचार करें
switch(a){
case 3: // ...
break;
case 5:
case 7: //...
break;
default: //...
}
इसमें संकलित किया जा सकता है
BTABL: *
B3: addr of 3 code
B5:
B7: addr of 5,7 code
load 0,1 ino reg X based on value
jump indirect through BTABL+x
क्योंकि आप स्पष्ट रूप से संकलक को बता रहे हैं कि उसे OR और समानता परीक्षणों की गणना करने की आवश्यकता नहीं है।
मेरे सीएस प्रोफेसर ने सुझाव दिया कि आप बयानों को स्विच न करें क्योंकि अक्सर लोग ब्रेक को भूल जाते हैं या इसका गलत तरीके से उपयोग करते हैं। मैं ठीक से याद नहीं कर सकता कि उसने क्या कहा था, लेकिन लाइनों के साथ कुछ ऐसा है जो कुछ सेमिनल कोड बेस को देख रहा है जो कि स्विच स्टेटमेंट के उदाहरण दिखाते हैं (वर्षों पहले) इसमें भी गलतियों का एक टन था।
कुछ ऐसा जो मैंने अभी देखा है कि आप संयोजन कर सकते हैं यदि / अन्यथा और स्विच स्टेटमेंट! बहुत उपयोगी जब preonditions की जाँच करने की जरूरत है।
if (string.IsNullOrEmpty(line))
{
//skip empty lines
}
else switch (line.Substring(0,1))
{
case "1":
Console.WriteLine(line);
break;
case "9":
Console.WriteLine(line);
break;
default:
break;
}
मुझे लगता है कि अगर स्थिति कोई प्रोग्राम की तरह है, तो स्विच और अधिक तेज़ है, जैसे:
किसी भी संख्या में प्रवेश करने के लिए एक प्रोग्राम लिखें (1 - 99 के बीच) और यह जांचें कि स्लॉट किसमें है) 1 - 9 फिर स्लॉट एक बी) 11 - 19 फिर स्लॉट दो सी) 21-29 फिर स्लॉट तीन और इतने पर 89- 99
इसके बाद अगर आपको कई स्थितियां बनानी हैं, लेकिन बेटा स्विच केस आपको बस टाइप करना है
स्विच (नहीं / 10)
और मामले पर 0 = 1-9, केस 1 = 11-19 और इसी तरह
यह इतना आसान होगा
ऐसे कई और उदाहरण भी हैं!
एक स्विच स्टेटमेंट मूल रूप से समानता के लिए एक तुलना है। कीबोर्ड इवेंट का स्विच स्टेटमेंट पर बहुत फायदा होता है, जब कोड लिखना और पढ़ना आसान होता है तो एक ifif स्टेटमेंट, एक {ब्रैकेट} को मिस करना भी परेशान कर सकता है।
char abc;
switch(abc)
{
case a: break;
case b: break;
case c: break;
case d: break;
}
एक ifif कथन अधिक होने पर बहुत अच्छा होता है, तो एक समाधान यदि (TheAmountOfApples अधिक है तो 5 &&AmountOfApples कम है, तो 10) अपने सेब को बचाएं अन्यथा (यदि TheAmountOfApples अधिक है तो 10) .AmountOfApples == 100) अपने सेब बेचें। मैं c # या c ++ नहीं लिखता लेकिन मैंने जावा सीखने से पहले इसे सीखा और वे करीबी भाषाएँ हैं।
स्विच स्टेटमेंट का एक संभावित नकारात्मक पहलू कई स्थितियों की कमी है। आपके पास (और) के लिए कई शर्तें हो सकती हैं, लेकिन एक स्विच में विभिन्न स्थितियों के साथ एक से अधिक मामले के बयान नहीं।
सरल बूलियन समीकरणों / अभिव्यक्तियों के दायरे से परे तर्क संचालन के लिए स्विच स्टेटमेंट उपयुक्त नहीं हैं। उन बूलियन समीकरणों / अभिव्यक्तियों के लिए, यह उचित रूप से उपयुक्त है, लेकिन अन्य तर्क संचालन के लिए नहीं।
यदि आप कथन में उपलब्ध तर्क के साथ बहुत अधिक स्वतंत्रता रखते हैं, लेकिन पठनीयता को नुकसान हो सकता है यदि IF कथन अनपेक्षित हो जाता है या खराब तरीके से संभाला जाता है।
दोनों का वहां पर संदर्भ है जो आप के साथ सामना कर रहे हैं।