2009-04-24 27 views
8

एक पंक्ति कार्यों के बारे में आप क्या सोचते हैं? क्या यह खराब है? एक लाभ जो मैं सोच सकता हूं वह यह है कि यह कोड को अधिक व्यापक बनाता है (यदि आप इसके लिए एक अच्छा नाम चुनते हैं)। उदाहरण के लिए:सी में एक लाइन काम करता है?

void addint(Set *S, int n) 
{ 
    (*S)[n/CHAR_SIZE] |= (unsigned char) pow(2, (CHAR_SIZE - 1) - (n % CHAR_SIZE)); 
} 

एक नुकसान यह है कि मैं के बारे में सोच सकते हैं कि यह कोड (पैरामीटर धक्का ढेर, एक समारोह के लिए कूद, मानकों पॉपिंग, आपरेशन कर रही है, कोड के लिए वापस कूद धीमा कर देती है - और केवल के लिए एक लाइन?)

क्या ऐसी लाइनों को कार्यों में रखना या उन्हें कोड में रखना बेहतर है? भले ही हम उन्हें केवल एक बार उपयोग करें?

बीटीडब्ल्यू, मुझे इसके बारे में कोई सवाल नहीं मिला है, इसलिए मुझे इस तरह के प्रश्न से पहले पूछे जाने पर क्षमा करें।

+6

आप कॉल ओवरहेड के बारे में चिंता कर रहे हैं, लेकिन फिर एक छोटे पूर्णांक की शक्ति में 2 को बढ़ाने के लिए वाह को बुला रहे हैं? ; -पी –

+0

ऐसा करने का बेहतर तरीका क्या हो सकता है? मैं जानना चाहता हूं। –

+2

2^x 2 के समान है << x अगर x एक पूर्णांक –

उत्तर

21

1-लाइन फ़ंक्शंस से डरो मत!

बहुत से प्रोग्रामर के पास 1-लाइन फ़ंक्शन के बारे में मानसिक अवरोध प्रतीत होता है, आपको नहीं करना चाहिए।

यदि यह कोड स्पष्ट और क्लीनर बनाता है, तो रेखा को फ़ंक्शन में निकालें।

प्रदर्शन शायद प्रभावित नहीं होगा।

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

एब्स्ट्रक्शन बेहतर डिजाइन की ओर ले जाता है। (यहां तक ​​कि कोड की एकल पंक्तियों के लिए)

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

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

शायद आपकी 1-लाइन अधिक रेखाएं होनी चाहिए।

यदि आपके पास कोड का एक बड़ा ब्लॉक है तो यह स्क्रीन रीयल एस्टेट पर सहेजने के लिए, एक पंक्ति पर बहुत सारी कार्यक्षमता को क्रैक करने के लिए मोहक हो सकता है। जब आप इस कोड को किसी फ़ंक्शन में माइग्रेट करते हैं, तो आप इन दबावों को कम करते हैं, जो आपको अपने जटिल 1-लाइनर को अधिक सरल कोड में विस्तारित करने के लिए अधिक इच्छुक हैं (जो इसकी पठनीयता और रखरखाव में सुधार करेगा)।

0

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

5

यदि एक से अधिक बार उपयोग किया जाता है, तो निश्चित रूप से इसे एक फ़ंक्शन बनाएं, और संकलक को इनलाइनिंग (संभावित रूप से फ़ंक्शन परिभाषा में "इनलाइन" जोड़ना) दें। (< समयपूर्व अनुकूलन के बारे में सामान्य सलाह यहां >)

0

क्या भाषा है? यदि आपका मतलब सी है, तो मैं inline क्वालीफायर का भी उपयोग करूंगा। सी ++ में, मेरे पास inline, boost.lamda का विकल्प है या lamdas के लिए C++ 0x मूल समर्थन आगे बढ़ रहा है।

5

चूंकि आपका उदाहरण सी (++) वाक्यविन्यास का उपयोग करने वाला प्रतीत होता है, इसलिए आप inline functions पर पढ़ना चाहेंगे जो एक साधारण फ़ंक्शन को कॉल करने के ऊपरी हिस्से को खत्म कर सकता है। यह कीवर्ड केवल संकलक के लिए अनुशंसा है हालांकि यह आपके द्वारा चिह्नित सभी कार्यों को रेखांकित नहीं कर सकता है, और अनमार्क किए गए कार्यों को इनलाइन करना चुन सकता है।

.NET में जेआईटी इनलाइन विधियों को रेखांकित करेगा जो इसे महसूस करते हैं, लेकिन आपके पास इस पर कोई नियंत्रण नहीं है कि यह क्यों या कब होता है, हालांकि (जैसा कि मैं इसे समझता हूं) डीबग बिल्ड कभी भी इनलाइन नहीं करेगा क्योंकि इससे स्रोत कोड संकलित आवेदन से मेल खाते हैं।

8

मैं एक पंक्ति में टक्कर लगी सभी प्रकार की तर्क और कार्यक्षमता रखने का प्रशंसक नहीं हूं। आपके द्वारा दिखाया गया उदाहरण एक गड़बड़ है और सार्थक परिवर्तनीय नामों का उपयोग करके और एक के बाद एक ऑपरेशन करने के दौरान कई लाइनों में विभाजित किया जा सकता है।

मैं दृढ़ता से अनुशंसा करते हैं, इस तरह के हर सवाल में, एक नज़र (इसे खरीदने के लिए, यह उधार ले, (नहीं) इसे डाउनलोड (मुक्त करने के लिए करते हैं)) this book: Robert C. Martin - Clean Code पर है। यह एक पुस्तक है जिसे प्रत्येक डेवलपर को देखना चाहिए।

यह आपको तुरंत एक अच्छा कोडर नहीं बनायेगा और यह आपको भविष्य में बदसूरत कोड लिखने से नहीं रोकेगा, हालांकि, जब आप बदसूरत कोड लिख रहे हों तो यह आपको एहसास देगा। यह आपको एक अधिक महत्वपूर्ण आंखों के साथ अपने कोड को देखने के लिए मजबूर करेगा और आपके कोड को अख़बार की कहानी की तरह पठनीय बनाने के लिए मजबूर करेगा।

1

एक पंक्ति कार्यों के साथ कुछ भी गलत नहीं है। जैसा कि बताया गया है कि संकलक के लिए उन कार्यों को इनलाइन करना संभव है जो किसी प्रदर्शन प्रदर्शन को हटा देंगे।

मैक्रोज़ पर फ़ंक्शंस को भी प्राथमिकता दी जानी चाहिए क्योंकि उन्हें डिबग, संशोधित, पढ़ने और अनपेक्षित साइड इफेक्ट्स होने की संभावना कम है।

यदि इसका उपयोग केवल एक बार किया जाता है तो उत्तर कम स्पष्ट होता है।किसी फ़ंक्शन में इसे स्थानांतरित करने से कॉलिंग फ़ंक्शन को कुछ जटिलता को नए फ़ंक्शन में ले जाकर & स्पष्ट हो सकता है।

-1

कभी कभी यह एक बुरा विचार पूर्वप्रक्रमक उपयोग करने के लिए नहीं है:

#define addint(S, n) (*S)[n/CHAR_SIZE] |= (unsigned char) pow(2, (CHAR_SIZE - 1) - (n % CHAR_SIZE)); 

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

#define addint(S, n) do { \ 
    unsigned char c = pow(2, (CHAR_SIZE -1) - (n % CHAR_SIZE)); \ 
    (*S)[n/CHAR_SIZE] |= c \ 
    } while(0) 
+2

प्रीप्रोसेसर शांत करें: "मुझे दुर्व्यवहार करें, मुझे दुर्व्यवहार करें, मुझे वांछित महसूस करें!" –

+1

मुझे लगा कि यह पूर्णता के लिए उल्लेख किया जाना चाहिए। यह इस मामले में सबसे अच्छा समाधान नहीं हो सकता है, क्योंकि कोई प्रकार की जांच नहीं है, लेकिन मैं इसका उल्लेख करता हूं। मैं यह नहीं कह रहा हूं "(एबी) प्रीप्रोसेसर का उपयोग करें", मैं कह रहा हूं "प्रीप्रोसेसर के बारे में मत भूलना"। यह एक उपकरण का बुरा नहीं है। –

+0

मैं मानता हूं कि प्रीप्रोसेसर एक बहुत ही उपयोगी टूल है। हालांकि, जब कुछ जटिल हो जाता है, तो इसे अक्सर इनलाइन करने के लिए बेहतर होता है, एएसएम डंप को देखें और देखें कि आपका कंपाइलर सहमत है या नहीं। 8/10 बार, संकलक सही होने जा रहा है। अब, यदि आपका कंपाइलर सिर्फ ए ** छेद है और आप इसे जानते हैं, तो प्रीप्रोसेसर रहता है। –