वापसी-वापसी या यदि-और-वापसी का उपयोग करना अधिक कुशल है?


141

मान लीजिए कि मेरे पास एक के ifसाथ एक बयान है return। दक्षता के दृष्टिकोण से, क्या मुझे उपयोग करना चाहिए

if(A > B):
    return A+1
return A-1

या

if(A > B):
    return A+1
else:
    return A-1

संकलित भाषा (C) या स्क्रिप्टेड एक (पायथन) का उपयोग करते समय क्या मुझे एक या दूसरे को पसंद करना चाहिए?


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

5
अपने कोड को छाँटने के लिए अपने संकलक पर भरोसा करना एक खतरनाक कदम है - और एक अचूक संकलक की आवश्यकता होती है। बेहतर होगा यदि आप जानते हैं कि आपके लिए क्या करना है!
एंड्रयू

1
यदि आप जो कर रहे हैं वह कल्पना द्वारा परिभाषित किया गया है, तो मुझे विश्वास नहीं है कि संकलक पर संदेह करने का कोई कारण है। यह लिखा गया होगा कि लोग आपसे कहीं ज्यादा होशियार हैं, और यह कहीं अधिक संभावना है कि आपने उनसे गलती की है।
होगा

7
राय के आधार पर इसे कैसे बंद किया जा सकता है? यह एक राय हो सकता है के बाद क्या आप जानते हैं दोनों के बीच कोई अंतर प्रदर्शन नहीं है। मैंने नहीं किया, और मुझे पूरा यकीन है कि बहुत सारे लोगों ने भी नहीं किया।
जॉर्ज लीताओ

1
हालांकि यह प्रश्न काफी लोकप्रिय है, लेकिन इसे किसी विशिष्ट भाषा के बिना सटीक रूप से उत्तर नहीं दिया जा सकता है, या अन्यथा, इस प्रारूप के लिए हर भाषा के लिए उत्तर देना बहुत लंबा होगा।
एमिल बर्जरोन

जवाबों:


195

चूंकि returnकथन वर्तमान फ़ंक्शन के निष्पादन को समाप्त करता है, इसलिए दो रूप समतुल्य हैं (हालांकि दूसरा पहले की तुलना में यकीनन अधिक पठनीय है)।

दोनों रूपों की दक्षता तुलनीय है, अंतर्निहित मशीन कोड को कूदना पड़ता है अगर ifहालत वैसे भी झूठी हो।

ध्यान दें कि पायथन एक सिंटैक्स का समर्थन करता है जो आपको returnअपने मामले में केवल एक बयान का उपयोग करने की अनुमति देता है :

return A+1 if A > B else A-1

32
C वह भी समर्थन करता है। return (A>B)?A+1:A-1;हालांकि इस तरह कोड लिखने से प्रदर्शन में कोई लाभ नहीं है । हमने जो कुछ भी हासिल किया है वह कोड को अस्पष्ट, अपठनीय और कुछ मामलों में निहित प्रकार के प्रचार के लिए अधिक असुरक्षित बनाने के लिए है।
लुंडिन

47
@ लुंडिन ने क्या कहा? अपठनीय? केवल उन लोगों के लिए जो टर्नरी ऑपरेटर को नहीं जानते हैं।
ग्लोगल

6
@ लुंडिन इस तर्क के बाद, <बुरा व्यवहार है क्योंकि -1 < 1uएक अप्रत्याशित परिणाम पैदा करता है।
ग्लोगल

3
@glglgl: नहीं, क्योंकि लोग उम्मीद करते हैं ?: ऑपरेटर को व्यवहार करना चाहिए जैसे-और, जो सच नहीं है। अगर कोई ऐसा कोड लिखता है -1 < 1u, जिस पर मुझे संदेह है, तो वे आसानी से बग को देख लेंगे। हालांकि बहुत सारे लोग मेरे द्वारा पोस्ट किए गए कोड के कुछ संस्करण लिखेंगे। मैंने इस तरह के बगों को बहुत बार देखा है? अंगूठे के एक नियम के रूप में, यदि भाषा आपको एक ही काम करने के लिए दो अलग-अलग तरीके देती है, तो उनमें से केवल एक का उपयोग करें, अपने मूड के आधार पर बेतरतीब ढंग से दोनों में से किसी को न चुनें।
लुंडिन

6
@ लुंडिन जो सावधान रहने के लिए एक तर्क है ?: सी में, लेकिन आप कह रहे हैं कि यह पायथन पर भी लागू होता है। क्या आप किसी भी उदाहरण की ओर इशारा कर सकते हैं, जहां पायथन में टर्नरी का उपयोग अप्रत्याशित परिणाम की ओर ले जाता है?
पीवीसी 23

33

से क्रोमियम की शैली गाइड:

वापसी के बाद अन्य का उपयोग न करें:

# Bad
if (foo)
  return 1
else
  return 2

# Good
if (foo)
  return 1
return 2

return 1 if foo else 2

1
धन्यवाद। +1। क्या मैं पूछ सकता हूं कि वापसी के बाद अन्य उपयोग क्यों नहीं किया जाए?
टिम

1
if-else कार्यात्मक रूप से समतुल्य है, लेकिन यह क्रिया है। अन्य अनावश्यक है।
skeller88

17
मैं आश्चर्यचकित था क्योंकि पहले अधिक स्पष्ट है और इस प्रकार बेहतर है।
टिम

4
आप या तो एक उचित मामला बना सकते हैं। इस निर्णय में सबसे महत्वपूर्ण बात यह है कि IMO कोड आधार के अनुरूप होना चाहिए।
skeller88

2
आप शायद अधिकांश मामलों में पाएंगे कि if-else-returnशाखाएँ लगभग कभी भी बराबर नहीं होती हैं (यदि वे हैं, तो आपको कहीं भी रिफैक्ट करना चाहिए; या तो एक switchनिर्माण का उपयोग करना चाहिए या पाइथन के लिए, एक तानाशाह / एक कॉल करने योग्य / आदि का उपयोग करते हुए)। इसलिए लगभग सभी if-else-returnगार्ड क्लॉज के मामले हैं और वे हमेशा परीक्षण योग्य हैं (परीक्षण किए गए अभिव्यक्ति का मजाक उड़ाए बिना) else
काउबर्ट

5

कोडिंग शैली के बारे में:

अधिकांश कोडिंग मानक कोई बात नहीं भाषा एक एकल समारोह से कई रिटर्न स्टेटमेंट को खराब अभ्यास के रूप में प्रतिबंधित करते हैं।

(हालांकि व्यक्तिगत रूप से मैं कहूंगा कि ऐसे कई मामले हैं जहां कई रिटर्न स्टेटमेंट मायने रखते हैं: पाठ / डेटा प्रोटोकॉल पार्सर, व्यापक कार्य संचालन आदि के साथ कार्य)

उन सभी उद्योग कोडिंग मानकों से सर्वसम्मति यह है कि अभिव्यक्ति के रूप में लिखा जाना चाहिए:

int result;

if(A > B)
{
  result = A+1;
}
else
{
  result = A-1;
}
return result;

दक्षता के बारे में:

उपरोक्त उदाहरण और प्रश्न में दो उदाहरण सभी दक्षता के मामले में पूरी तरह से समान हैं । इन सभी मामलों में मशीन कोड को ए> बी, फिर ए + 1 या ए -1 गणना के लिए शाखा की तुलना करना होगा, फिर उस परिणाम को सीपीयू रजिस्टर या स्टैक पर स्टोर करना होगा।

संपादित करें:

सूत्रों का कहना है:

  • MISRA-C: 2004 नियम 14.7, जो बारी में उद्धृत करता है ...:
  • आईईसी 61508-3। भाग 3, तालिका B.9।
  • आईईसी 61508-7। C.2.9।

37
क्या आप सुनिश्चित हैं कि एकल-वापसी धर्म ने अधिकांश कोडिंग मानकों को संक्रमित किया है? यह भयावह होगा।
डैनियल फिशर

7
मैं कहूंगा कि नियम का ज्यादातर समय मतलब नहीं होता है। मैं उचित बिंदुओं पर रिटर्न के साथ कोड को अधिक पठनीय और आसान ढूंढता हूं। लेकिन वह सिर्फ मैं हूं। हालाँकि, मैंने प्रति कंपनी / प्रोजेक्ट कोडिंग मानकों के बारे में सोचा था, न कि MISRA जैसी चीज़ों पर जहाँ कभी-कभार मुहावरेदार नुस्खे कभी-कभार ही मेरी योग्यता हो सकते हैं। मुझे आशा है कि अधिकांश एकल निकास बिंदु विचार में नहीं खरीदा था।
डैनियल फिशर

3
@DanielFischer: मेरी कंपनी के लिए डिज़ाइन किए गए MISRA पर आधारित C ​​कोडिंग मानक में, मेरे पास नियम है "फ़ंक्शन के अंत में एक फ़ंक्शन में केवल एक ही निकास बिंदु होगा, जब तक कि निकास का एक भी बिंदु कोड नहीं बनाता है। कम पठनीय ”। तो यह MISRA-C है लेकिन नियम के अपवाद के साथ। यदि आप एक उन्नत पार्सर फ़ंक्शन लिखते हैं, जो 10 डिफरेंशियल एरर्स कह सकता है, तो नेस्टेड ब्रेसेस का स्तर कोड को पूरी तरह से अपठनीय बना देता है - ऐसे में त्रुटि का सामना होने पर तुरंत वापस लौटना अधिक समझदार होगा।
लुंडिन

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

1
@ स्पर्सबस मैं पूरी तरह से सहमत हूं और एकल वापसी के खिलाफ चक्रीय जटिलता एक अच्छा तर्क है। और मैं कई बार इस बारे में MISRA समिति को रोक रहा हूं, उदाहरण के लिए इसे देखें । कम से कम नियम MISRA-C: 2012 में सलाहकार के लिए डाउनग्रेड हो गया।
लंडिन

3

किसी भी समझदार संकलक के साथ, आपको कोई अंतर नहीं देखना चाहिए; वे समान मशीन कोड के लिए संकलित किया जाना चाहिए क्योंकि वे बराबर हैं।


2

यह शैली का सवाल है (या वरीयता) क्योंकि दुभाषिया परवाह नहीं करता है। व्यक्तिगत रूप से मैं एक फ़ंक्शन के अंतिम विवरण को नहीं बनाने की कोशिश करूंगा जो फ़ंक्शन बेस के अलावा अन्य इंडेंट स्तर पर मान लौटाता है। उदाहरण 1 में दूसरा अस्पष्ट है, यदि केवल थोड़ा, जहां फ़ंक्शन का अंत है।

वरीयता द्वारा मैं उपयोग करता हूं:

return A+1 if (A > B) else A-1

चूंकि यह फ़ंक्शन में अंतिम विवरण (जैसा कि पहले ही उल्लेख किया गया है) और अनिवार्य शैली के मध्यवर्ती परिणामों से बचने के अच्छे कार्यात्मक प्रोग्रामिंग प्रतिमान के रूप में एकल रिटर्न स्टेटमेंट होने के दोनों अच्छे सम्मेलन का पालन करता है।

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

कुछ पोस्टरों में ऑपरेशन की गति का उल्लेख किया गया है। रन-टाइम की गति मेरे लिए माध्यमिक है क्योंकि यदि आपको निष्पादन की गति की आवश्यकता है तो पायथन उपयोग करने के लिए सबसे अच्छी भाषा नहीं है। मैं पायथन का उपयोग इसकी कोडिंग की दक्षता के रूप में करता हूं (यानी त्रुटि मुक्त कोड लिखना) जो मेरे लिए मायने रखता है।


1
अगर कोई उपयोगकर्ता मेरे जवाब को कम करने जा रहा है, तो मैं एक टिप्पणी की सराहना करूंगा कि उन्होंने क्यों सोचा कि मैं गलत था।
स्टीफन एलवुड

मैं शायद पठनीय उद्देश्यों के लिए इसे प्रति पंक्ति १ पंक्ति बनाने से पहले सिर्फ एक पंक्ति बनाऊंगा। var n = 1 if (A > B) else -1 return A+n
percebus

@percebus कुछ मामलों में मैं सहमत होता अगर चर नाम अर्थ बढ़ा सकता है। उदाहरण के लिए: 'code' Move_x = 1 यदि my_x <प्रतिद्वंद्वी_x और -1 # प्रतिद्वंद्वी की ओर बढ़ें
Stephen Ellwood

BTW मैं वास्तव में अपने जवाब upvoted। यदि आप देखते हैं कि मेरा उत्तर समान है
मानसबोध २ see ’१। को १२:१५

2

elseजब संभव हो मैं व्यक्तिगत रूप से ब्लॉक से बचता हूं । एंटी-इफ कैंपेन देखें

इसके अलावा, वे लाइन के लिए 'अतिरिक्त' चार्ज नहीं करते हैं, आप जानते हैं: पी

"सरल जटिल से बेहतर है" और "पठनीयता राजा है"

delta = 1 if (A > B) else -1
return A + delta

2
क्यों गिरा वोट? एक 'पायथोनिक' उत्तर है। आप इसे एक पसंदीदा जवाब नहीं मान सकते हैं। लेकिन एक अमान्य नहीं है। मैं भी KISS सिद्धांत अनुसरण कर रही हूं en.wikipedia.org/wiki/KISS_principle
percebus

3
जब से यह पठनीयता और सरल पर स्कोर करता है, मैंने आपके उत्तर को बदल दिया। मुझे व्यक्तिगत रूप से यह अपमानजनक लगता है कि कोई व्यक्ति मुझे वोट देने के बिना मुझे वोट देता है कि मेरा जवाब सक्रिय रूप से नकारात्मक क्यों है।
स्टीफन एलवुड

1
एंटी-इफ कैंपेन के बारे में पहले नहीं सुना था लेकिन समझ सकते हैं कि इफ्स खतरनाक क्यों हो सकता है। मैं हमेशा एक if स्टेटमेंट द्वारा बताए गए कोड की मात्रा को सीमित करने की कोशिश करता हूं और तानाशाही का उपयोग करने के लिए एलिफ पेड़ों को फिर से लिखने की कोशिश करता हूं। हालांकि यह थोड़ा ऑफ-टॉपिक हो रहा है।
स्टीफन एलवुड

1
@StephenEllwood dictएस से बचने के लिए एस का उपयोग करना एक बहुत बुरा विचार प्रदर्शन-वार है।
बछसौ

@ बछसौ आप शायद सही कह रहे हैं। मुझे प्रदर्शन के बारे में चिंता करने की ज़रूरत नहीं है क्योंकि मेरी सभी स्क्रिप्ट सेकंड में चलती हैं। मेरे लिए पठनीयता आमतौर पर प्रदर्शन को प्रभावित करती है। चूंकि मैं एक पूर्णकालिक प्रोग्रामर नहीं हूं; वे सिर्फ एक अंत के लिए एक साधन हैं।
स्टीफन एलवुड

1

संस्करण A सरल है और इसीलिए मैं इसका उपयोग करूंगा।

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


1

मुझे पता है कि प्रश्न को अजगर को टैग किया गया है, लेकिन इसमें गतिशील भाषाओं का उल्लेख है, इसलिए मैंने सोचा कि मुझे इस बात का उल्लेख करना चाहिए कि यदि वास्तव में विवरण में रिटर्न टाइप है तो आप कुछ ऐसा कर सकते हैं

def foo
  rv = if (A > B)
         A+1
       else
         A-1
       end
  return rv 
end

या क्योंकि यह भी निहित प्रभाव बस है

def foo 
  if (A>B)
    A+1
  else 
    A-1
  end
end

जो बहुत अच्छी तरह से कई रिटर्न नहीं होने की शैली के मुद्दे के आसपास हो जाता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.