क्या पढ़ने योग्य कोड के साथ अनुकूलित कोड को बदलना ठीक है?


78

कभी-कभी आप ऐसी स्थिति में भाग लेते हैं जहाँ आपको कुछ मौजूदा कोड का विस्तार / सुधार करना होता है। आप देखते हैं कि पुराना कोड बहुत दुबला है, लेकिन इसका विस्तार करना भी मुश्किल है, और पढ़ने में समय लगता है।

क्या इसे आधुनिक कोड के साथ बदलना एक अच्छा विचार है?

कुछ समय पहले मुझे दुबला दृष्टिकोण पसंद आया था, लेकिन अब, यह मुझे लगता है कि उच्च अमूर्तता, बेहतर इंटरफेस और अधिक पठनीय, विस्तार योग्य कोड के पक्ष में बहुत अधिक अनुकूलन का त्याग करना बेहतर है।

संकलक के रूप में अच्छी तरह से बेहतर हो रहे हैं, इसलिए चीजों struct abc = {}को चुपचाप memsetएस में बदल दिया जाता है , shared_ptrबहुत ज्यादा कच्चे सूचक टिड्डिंग के समान कोड का उत्पादन कर रहे हैं, टेम्पलेट्स सुपर अच्छा काम कर रहे हैं क्योंकि वे सुपर लीन कोड का उत्पादन करते हैं, और इसी तरह।

लेकिन फिर भी, कभी-कभी आपको कुछ अस्पष्ट तर्क के साथ स्टैक आधारित सरणियाँ और पुराने सी फ़ंक्शन दिखाई देते हैं, और आमतौर पर वे महत्वपूर्ण पथ पर नहीं होते हैं।

क्या इस तरह के कोड को बदलना एक अच्छा विचार है अगर आपको इसके किसी छोटे से हिस्से को छूना है?


20
अधिकांश समय पठनीयता और अनुकूलन का विरोध नहीं किया जाता है।
deadalnix

23
क्या कुछ टिप्पणियों से पठनीयता में सुधार हो सकता है?
यतनउत्तर

17
यह चिंताजनक है कि OOP-ification को 'आधुनिक कोड' माना जाता है
जेम्स

7
स्लैकवेयर दर्शन की तरह: यदि यह टूटा हुआ नहीं है, तो इसे ठीक न करें, कम से कम आपके पास इसे करने का एक बहुत अच्छा कारण है
ओस्दामव

5
अनुकूलित कोड से, क्या आपका मतलब वास्तविक अनुकूलित कोड है, या तथाकथित अनुकूलित कोड?
dan04

जवाबों:


115

कहाँ पे?

  • Google-स्केल वेबसाइट के मुख पृष्ठ पर, यह स्वीकार्य नहीं है। जितना हो सके चीजों को जल्दी रखें।

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

सामान्य तौर पर, आप जिस कोड पर काम कर रहे हैं , उसके लिए गैर-कार्यात्मक आवश्यकताएं क्या हैं? यदि एक कार्रवाई 900 एमएस के तहत करनी चाहिए। दिए गए संदर्भ में (मशीन, लोड, आदि) समय का 80%, और वास्तव में, यह 200 एमएस के तहत प्रदर्शन करता है। 100% समय, निश्चित रूप से, कोड को अधिक पठनीय बनाते हैं भले ही यह प्रदर्शन को थोड़ा प्रभावित करे। यदि दूसरी ओर एक ही क्रिया दस सेकंड के तहत कभी नहीं की जाती है, तो ठीक है, आपको यह देखने की कोशिश करनी चाहिए कि प्रदर्शन में गलत क्या है (या पहली जगह में आवश्यकता)।

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


47
+1! यदि आपके पास संख्याएँ नहीं हैं, तो कुछ संख्याएँ प्राप्त करें। यदि आपके पास संख्याएँ प्राप्त करने का समय नहीं है, तो आपके पास इसे बदलने का समय नहीं है।
ताकारॉय

49
अक्सर ऐसा नहीं है, डेवलपर्स मिथक और गलतफहमी के आधार पर "अनुकूलन" कर रहे हैं, उदाहरण के लिए, यह मानकर कि "C" "C ++" से अधिक तेज़ है और C ++ से बचने के लिए एक सामान्य एहसास है कि चीजें बिना संख्याओं के तेजी से आगे बढ़ती हैं। मुझे एक सी डेवलपर की याद दिलाता है जिसका मैंने अनुसरण किया gotoथा जो सोचा था कि लूप्स की तुलना में तेज था। विडंबना यह है कि आशावादी ने छोरों के साथ बेहतर किया, इसलिए उन्होंने कोड को धीमा और पढ़ने के लिए कठिन बना दिया ।
स्टीवन बर्नैप

6
एक और उत्तर जोड़ने के बजाय, मैंने इस उत्तर को +1 किया। यदि कोड के टुकड़े समझना महत्वपूर्ण है, तो उन्हें अच्छी तरह से टिप्पणी करें। मैंने एक C / C ++ / असेंबली परिवेश में दर्जनों योगदानकर्ताओं के साथ विरासत कोड के साथ एक दशक पुराना काम किया। यदि कोड काम करता है, तो इसे अकेला छोड़ दें और काम पर वापस जाएं।
क्रिस के

इसलिए मैं केवल पठनीय कोड लिखता हूं। प्रदर्शन को कुछ हॉट-स्पॉट काटने तक पहुँचा जा सकता है।
लुका

36

आमतौर पर, नहीं

कोड बदलने से सिस्टम में अन्य जगहों पर अप्रत्याशित रूप से खटखटाने की समस्या पैदा हो सकती है (जो कभी-कभी किसी परियोजना में बाद में तब तक किसी का ध्यान नहीं जा सकता है यदि आपके पास ठोस इकाई और धुएं के परीक्षण नहीं हैं)। मैं आमतौर पर "अगर यह टूट नहीं गया है, तो इसे ठीक न करें" मानसिकता से जाएं।

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

बेशक, प्रोफाइल, प्रोफाइल, प्रोफाइल , खासकर अगर यह एक महत्वपूर्ण पथ क्षेत्र है।


2
हां, लेकिन आप मानते हैं कि अनुकूलन की आवश्यकता थी। हम हमेशा नहीं जानते कि क्या यह था, और हम शायद यह पहले निर्धारित करना चाहते हैं।
हेलेम

2
@ हाइलम: नहीं, मुझे लगता है कि कोड के रूप में काम करता है। मैं यह भी मानता हूं कि कोड को रिफलेक्ट करने से सिस्टम में अन्य जगहों पर नॉक-ऑन समस्याएँ पैदा होंगी (जब तक कि आप कोड के एक तुच्छ भाग से निपट रहे हों जिसमें कोई बाहरी निर्भरता न हो)।
डेमियन ब्रेख्त

इस उत्तर में कुछ सच्चाई है, और विडंबना यह है कि क्योंकि नॉक-ऑन मुद्दे शायद ही कभी डेवलपर्स द्वारा प्रलेखित, समझे गए, संप्रेषित, या यहां तक ​​कि ध्यान दिए जाते हैं। यदि डेवलपर्स को अतीत में हुए मुद्दों की गहरी समझ है, तो उन्हें पता होगा कि क्या मापना है , और कोड परिवर्तन करने में अधिक आत्मविश्वास होगा।
rwong

29

संक्षेप में: यह निर्भर करता है

  • क्या आप वास्तव में अपने refactored / संवर्धित संस्करण की आवश्यकता या उपयोग करने जा रहे हैं?

    • क्या कोई ठोस लाभ है, तत्काल या दीर्घकालिक?
    • क्या यह लाभ केवल बनाए रखने के लिए है, या वास्तव में वास्तुशिल्प है?
  • क्या वास्तव में इसे अनुकूलित करने की आवश्यकता है?

    • क्यों?
    • आपको किस लक्ष्य के लिए लक्ष्य प्राप्त करने की आवश्यकता है?

विवरण में

क्या आपको साफ, चमकदार सामान की आवश्यकता है?

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

अधिक विशेष रूप से, यह जानते हैं:

ओवर-इंजीनियरिंग जैसी कोई चीज होती है

यह एक विरोधी पैटर्न है, और यह अंतर्निहित मुद्दों के साथ आता है:

  • यह अधिक एक्सटेंसिबल हो सकता है , लेकिन इसका विस्तार करना आसान नहीं हो सकता है ,
  • यह समझना आसान नहीं हो सकता है ,
  • अंतिम, लेकिन निश्चित रूप से कम से कम यहां नहीं: आप पूरे कोड को धीमा कर सकते हैं।

कुछ भी उल्लेख कर KISS सिद्धांत एक संदर्भ के रूप, लेकिन यहाँ यह जवाबी सहज है: अनुकूलित रास्ता आसान तरीका या cleany architectured तरीका है? उत्तर आवश्यक नहीं है, जैसा कि नीचे दिए गए बाकी हिस्सों में बताया गया है।

आपको इसकी आवश्यकता नहीं है

YAGNI सिद्धांत अन्य मुद्दे के साथ पूरी तरह से orthogonal नहीं है, लेकिन यह अपने आप को सवाल पूछने के लिए मदद करता है: आप इसे जरूरत के लिए जा रहे हैं?

क्या अधिक जटिल वास्तुकला वास्तव में आपके लिए एक लाभ प्रस्तुत करता है, इसके अलावा अधिक बनाए रखने की उपस्थिति देने के अलावा?

अगर यह टूटा नहीं है, तो इसे ठीक मत करो

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

यह स्वाभाविक है कि हम "कोड" को सुधारना चाहते हैं या यहाँ तक कि इसे अनजाने में भी स्पर्श कर सकते हैं, जैसा कि हम इसे पढ़ने की कोशिश करते हैं। यह एक अच्छी बात है, क्योंकि इसका मतलब है कि हम राय रखते हैं और आंतरिक लोगों की गहरी समझ प्राप्त करने की कोशिश करते हैं, लेकिन यह हमारे कौशल-स्तर, हमारे ज्ञान (आप कैसे तय करते हैं कि क्या बेहतर है या नहीं?) के लिए बाध्य है, नीचे दिए गए अनुभाग देखें। ...), और हम जो कुछ भी सोचते हैं, उसके बारे में हम सोचते हैं कि हम सॉफ्टवेयर जानते हैं ...:

  • वास्तव में करता है,
  • वास्तव में करने की जरूरत है,
  • अंततः करने की आवश्यकता होगी,
  • और यह कितनी अच्छी तरह से करता है।

क्या वास्तव में इसे अनुकूलित करने की आवश्यकता है?

यह सब कहा, यह पहली जगह में "अनुकूलित" क्यों था? वे कहते हैं कि समय से पहले अनुकूलन सभी बुराई की जड़ है, और यदि आप अवांछित और प्रतीत होता है अनुकूलित कोड देखते हैं, तो आमतौर पर आप यह मान सकते हैं कि शायद अनुकूलन के नियमों का पालन नहीं किया गया था, अनुकूलन के प्रयास की आवश्यकता नहीं थी और यह सिर्फ यह था सामान्य विकासकर्ता की हैरिस में लात मारना। अभी भी फिर से, शायद यह सिर्फ तुम्हारी बात हो रही है।

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

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

नाप, नाप, नाप

जैसा कि Google के लोग अब कर रहे हैं, यह डेटा के बारे में है! यदि आप इसे डेटा के साथ वापस कर सकते हैं, तो यह आवश्यक है।

इस नहीं तो पुराने कहानी है कि हर $ 1 के विकास में खर्च के लिए यह के बाद किया जाएगा है कम से कम परीक्षण में $ 1 और कम से कम समर्थन में $ 1 (लेकिन वास्तव में, यह एक बहुत अधिक है)।

परिवर्तन कई चीजों को प्रभावित करता है:

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

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

और आप प्रबंधक के लिए, इसका मतलब है कि इसे वर्तमान विकास योजना में फिट करना, इसलिए इसके बारे में संवाद करें और उग्र गाय-लड़के / पनडुब्बी / ब्लैक-ऑप्स कोडिंग में न पड़ें।


सामान्य रूप में...

हाँ लेकिन...

मुझे गलत मत समझिए, सामान्य तौर पर, मैं ऐसा करने के पक्ष में हूं कि आप सुझाव क्यों देते हैं, और मैं अक्सर इसकी वकालत करता हूं। लेकिन आपको दीर्घकालिक लागत के बारे में पता होना चाहिए।

एक आदर्श दुनिया में, यह सही समाधान है:

  • कंप्यूटर हार्डवेयर समय के साथ बेहतर होते जाते हैं,
  • कंपाइलर और रनटाइम प्लेटफॉर्म समय के साथ बेहतर हो जाते हैं,
  • आपको क्लोज-टू-परफेक्ट, क्लीन, मेंटेनेंस और रीडेबल कोड मिलता है।

प्रयोग में:

  • आप इसे बदतर बना सकते हैं

    आपको इसे देखने के लिए अधिक नेत्रगोलक की आवश्यकता है, और जितना अधिक आप इसे जटिल करते हैं, उतनी ही नेत्रगोलक की आपको आवश्यकता होती है।

  • आप भविष्य की भविष्यवाणी नहीं कर सकते

    अगर आपको कभी इसकी आवश्यकता होगी तो आप पूरी निश्चयता के साथ नहीं जान सकते, भले ही आपको "एक्सटेंशन" की आवश्यकता न हो, पुराने रूप में लागू करने के लिए आपको आसान और तेज़ होना चाहिए, और यदि खुद को सुपर-अनुकूलित करने की आवश्यकता होगी ।

  • यह प्रबंधन के दृष्टिकोण से, प्रत्यक्ष लाभ के लिए एक बड़ी लागत का प्रतिनिधित्व करता है।

इसे प्रक्रिया का हिस्सा बनाएं

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

यदि आपके पास इस तरह के निर्णय लेने की प्रक्रिया है, तो आप व्यक्तिगत रूप से उनसे किनारा कर लेते हैं:

  • यदि आप चीजों को सही ढंग से परखते हैं, तो आप जल्दी जान जाएंगे कि क्या चीजें टूटी हुई हैं,
  • यदि आप उन्हें मापते हैं, तो आपको पता चलेगा कि क्या वे सुधर गए हैं,
  • यदि आप इसकी समीक्षा करते हैं, तो आपको पता चल जाएगा कि क्या यह लोगों को फेंकता है।

टेस्ट कवरेज, प्रोफाइलिंग और डेटा-कलेक्शन मुश्किल हैं

लेकिन, निश्चित रूप से, आपके परीक्षण कोड और मैट्रिक्स उन्हीं मुद्दों से पीड़ित हो सकते हैं जिन्हें आप अपने वास्तविक कोड से बचने की कोशिश कर रहे हैं: क्या आप सही चीजों का परीक्षण करते हैं, और क्या वे भविष्य के लिए सही चीज हैं, और क्या आप सही माप करते हैं बातें?

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

कोड समीक्षा विकास टीम के दालान परीक्षण हैं

और मुझे लगता है कि अंतिम भाग यहां महत्वपूर्ण है: कोड समीक्षा करें। यदि आप उन्हें एकल बनाते हैं तो आपको अपने सुधारों का मूल्य नहीं पता होगा। कोड समीक्षाएं हमारे "हॉलवे परीक्षण" हैं: बग्स का पता लगाने और ओवर-इंजीनियरिंग और अन्य विरोधी पैटर्न का पता लगाने के लिए, और यह सुनिश्चित करने के लिए कि कोड आपकी टीम की क्षमताओं के अनुरूप है, रेमंड के संस्करण का पालन ​​करें । "सबसे अच्छा" कोड होने का कोई मतलब नहीं है अगर कोई और नहीं, लेकिन आप इसे समझ सकते हैं और इसे बनाए रख सकते हैं, और यह दोनों क्रिप्टिक अनुकूलन और 6-परतों के साथ गहरे वास्तुशिल्प डिजाइनों के लिए जाता है।

शब्दों को बंद करते समय, याद रखें:

हर कोई जानता है कि डिबगिंग पहले स्थान पर एक कार्यक्रम लिखने के रूप में दोगुना कठिन है। इसलिए यदि आप उतने ही चतुर हैं जितना आप लिखते समय हो सकते हैं, तो आप इसे कैसे डिबग करेंगे? - ब्रायन कर्निघन


"अगर यह टूटा नहीं है, तो इसे ठीक मत करो" refactoring के खिलाफ जाता है। इससे कोई फर्क नहीं पड़ता कि कुछ काम करता है, अगर अचूक है, तो बदलने की जरूरत है।
मियामोतो अकीरा

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

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

@MiyamotoAkira: छोटे वाक्य और विचारों के बयान ज्यादा व्यक्त नहीं कर सकते हैं। वे आपके चेहरे पर होने का मतलब है, और पक्ष में विकसित होने के लिए, मुझे लगता है। मैं अपने आप में बहुत संभव के रूप में, भले ही अक्सर एक बड़ी सुरक्षा जाल के बिना या बहुत कारण के बिना कोड की समीक्षा करने और छूने के कारक में बहुत हूं। यदि यह गंदा है, तो आप इसे साफ करते हैं। लेकिन, इसी तरह, मैं भी कुछ बार जल गया। और अभी भी जल जाएगा। जब तक यह 3 डिग्री नहीं है, तब तक मुझे इससे कोई आपत्ति नहीं है, अब तक यह दीर्घकालिक लाभ के लिए हमेशा अल्पकालिक जलता रहा है।
जाइल

8

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

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

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

एक बार में कोड के केवल एक हिस्से को बदलें और देखें कि रिफैक्टरिंग के प्रत्येक दौर के बाद यह प्रदर्शन को कैसे प्रभावित करता है।


8

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

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

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

यदि अनुकूलन अधिक पुराना है, तो नए तरीके तेज़ होने के साथ-साथ अधिक पठनीय भी हो सकते हैं।

अंतत: यह आपके बॉस के लिए एक सवाल है। यह किसी ऐसी चीज को रिफलेक्टर करने में सक्षम है जिसे अनुकूलित किया गया है और यह सुनिश्चित करने के लिए कि परिवर्तन अंतिम परिणाम को प्रभावित नहीं करता है और यह पुराने तरीके की तुलना में कम से कम या कम से कम स्वीकार करता है। वह चाहता है कि आप कुछ मिनटों की कोडिंग के समय को बचाने के लिए उच्च जोखिम वाले कार्य को करने के बजाय अन्य क्षेत्रों में अपना समय बिताएं। या वह इस बात से सहमत हो सकता है कि कोड को समझना कठिन है और उसे लगातार हस्तक्षेप की आवश्यकता है और अब बेहतर तरीके उपलब्ध हैं।


6

यदि प्रोफाइलिंग से पता चलता है कि अनुकूलन अनावश्यक है (यह महत्वपूर्ण खंड में नहीं है) या इससे भी खराब रनटाइम है (खराब समयपूर्व अनुकूलन के परिणामस्वरूप) तो सुनिश्चित करें कि पठनीय कोड के साथ प्रतिस्थापित करें जो बनाए रखना आसान है

यह भी सुनिश्चित करें कि कोड उपयुक्त परीक्षणों के साथ समान व्यवहार करता है


5

इसे व्यवसायिक दृष्टिकोण से सोचें। परिवर्तन की लागत क्या है? परिवर्तन करने के लिए आपको कितना समय चाहिए और कोड को बढ़ाने या बनाए रखने के लिए अधिक आसान बनाकर आप लंबे समय में कितना बचा पाएंगे? अब उस समय के लिए एक मूल्य टैग संलग्न करें और प्रदर्शन को कम करके खोए हुए धन की तुलना करें। हो सकता है कि आपको खोए हुए प्रदर्शन के लिए एक सर्वर जोड़ने या अपग्रेड करने की आवश्यकता हो। शायद उत्पाद अब आवश्यकताओं को पूरा नहीं करता है और अब बेचा नहीं जा सकता है। शायद कोई नुकसान न हो। हो सकता है कि परिवर्तन से मजबूती बढ़े और समय की बचत हो। अब अपना निर्णय लें।

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


4

असल में, आप पूछ रहे हैं कि क्या रिफैक्टिंग एक सार्थक उद्यम है। इसका उत्तर निश्चित रूप से हां है।

परंतु...

... आपको इसे सावधानी से करने की आवश्यकता है। आपको किसी भी कोड के लिए ठोस इकाई, एकीकरण, कार्यात्मक और प्रदर्शन परीक्षण की आवश्यकता होती है, जिसे आप रिफलेक्ट कर रहे हैं। आपको आश्वस्त होने की आवश्यकता है कि वे वास्तव में सभी आवश्यक कार्यक्षमता का परीक्षण करते हैं। आपको उन्हें आसानी से और बार-बार चलाने की क्षमता चाहिए। एक बार आपके पास ऐसा हो, तो आपको समान कार्यक्षमता वाले नए घटकों के साथ घटकों को बदलने में सक्षम होना चाहिए।

मार्टिन फाउलर ने इस पर पुस्तक लिखी ।


3

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

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


3

यदि यह कोड का एक छोटा सा टुकड़ा है जो किसी कठिन तरीके से अपेक्षाकृत कुछ सरल करता है, तो मैं "त्वरित समझ" को एक विस्तारित टिप्पणी और / या अप्रयुक्त वैकल्पिक कार्यान्वयन में स्थानांतरित कर दूंगा, जैसे

#ifdef READABLE_ALT_IMPLEMENTATION

   double x=0;
   for(double n: summands)
     x += n;
   return x;

#else

   auto subsum = [&](int lb, int rb){
          double x=0;
          while(lb<rb)
            x += summands[lb++];
          return x;
        };
   double x_fin=0;
   for(double nsm: par_eval( subsum
                           , partitions(n_threads, 0, summands.size()) ) )
     x_fin += nsm;
   return x_fin;

#endif

3

जवाब है, सामान्यता की हानि के बिना, हाँ। जब आप कोड को पढ़ना मुश्किल देखते हैं, और ज्यादातर मामलों में खराब कोड को हटाते हैं, तो हमेशा आधुनिक कोड जोड़ें। मैं निम्नलिखित प्रक्रिया का उपयोग करता हूं:

  1. प्रदर्शन परीक्षण और समर्थन प्रोफाइलिंग जानकारी देखें। यदि कोई प्रदर्शन परीक्षण नहीं है, तो क्या सबूत के बिना दावा किया जा सकता है बिना सबूत के खारिज किया जा सकता है। दावा करें कि आपका आधुनिक कोड तेज़ है और पुराने कोड को हटा दें। यदि कोई भी (यहां तक ​​कि खुद भी) तर्क देता है, तो उसे साबित करने के लिए प्रोफाइल कोड लिखने के लिए कहें जो कि तेज है।
  2. यदि प्रोफाइलिंग कोड मौजूद है, तो वैसे भी आधुनिक कोड लिखें। इसे कुछ इस तरह नाम दें <function>_clean()। फिर, खराब कोड के खिलाफ अपने कोड को "रेस" करें। यदि आपका कोड बेहतर है, तो पुराना कोड हटा दें।
  3. यदि पुराना कोड तेज है, तो अपने आधुनिक कोड को वैसे भी छोड़ दें। यह दूसरे कोड का क्या करना है, इसके लिए अच्छे प्रलेखन के रूप में कार्य करता है, और "रेस" कोड होने के बाद से, आप इसे प्रदर्शन विशेषताओं और दो रास्तों के बीच अंतर के दस्तावेजीकरण के लिए चला सकते हैं। आप कोड व्यवहार में अंतर के लिए इकाई परीक्षण भी कर सकते हैं। महत्वपूर्ण रूप से, आधुनिक कोड एक दिन "गारंटीकृत" कोड को हरा देगा, गारंटीकृत। फिर आप बुरे कोड को हटा सकते हैं।

QED।


3

अगर मैं मरने से पहले दुनिया को एक चीज (सॉफ्टवेयर के बारे में) सिखा सकता था, तो मैं इसे सिखाऊंगा कि "प्रदर्शन बनाम एक्स" एक झूठी दुविधा है।

रीफैक्टरिंग को आमतौर पर पठनीयता और विश्वसनीयता के लिए एक वरदान के रूप में जाना जाता है, लेकिन यह आसानी से अनुकूलन का समर्थन कर सकता है। जब आप रिफ्लेक्टरिंग की एक श्रृंखला के रूप में प्रदर्शन में सुधार करते हैं, तो आप एप्लिकेशन को तेजी से आगे बढ़ाते हुए कैंपसाइट नियम का सम्मान कर सकते हैं। यह वास्तव में, कम से कम मेरी राय में, ऐसा करने के लिए नैतिक रूप से आप पर निर्भर है।

उदाहरण के लिए, इस प्रश्न के लेखक को कोड का एक पागल टुकड़ा सामना करना पड़ा है। यदि यह व्यक्ति मेरे कोड को पढ़ रहे थे, तो वे पाएंगे कि पागल भाग 3-4 पंक्तियों का है। यह अपने आप में एक विधि है, और विधि नाम और विवरण इंगित करता है कि विधि क्या कर रही है। इस विधि में 2-6 पंक्तियाँ होंगी जिसमें इनलाइन टिप्पणियों का वर्णन किया जाएगा कि कैसे एचओवी का पागल कोड सही उत्तर प्राप्त करता है, बावजूद इसके संदिग्ध उपस्थिति।

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


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

दुर्भाग्य से, ऐसे मामलों में भी जहां इस तरह के ऑपरेशन को कुशलता से किया जाना संभव है, अक्सर 5,000 पुनरावृत्तियों (और कुछ मामलों में 45,000!) के लिए "भारी" छोरों को चलाने के लिए आवश्यक होगा। यदि किसी ऑपरेशन को बल्क ऐरे कॉपियों जैसी चीज़ों में घटाया जा सकता है, तो उन्हें अत्यधिक वेतन देने वाले प्रमुख भुगतान के लिए अनुकूलित किया जा सकता है। यदि प्रत्येक लूप पुनरावृत्ति को एक दर्जन चरण करने की आवश्यकता होती है, तो उनमें से किसी को विशेष रूप से अच्छी तरह से अनुकूलित करना कठिन है।
सुपरकैट

2

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

यदि आप करते हैं चीजों को बदलने के लिए अधिक पठनीय और बढ़ाई होने के लिए तय: इससे पहले कि आप एक परिवर्तन, बेंचमार्क से कम उम्र के कोड बनाने के भारी बोझ। इससे भी बेहतर अगर आप एक पुराने दस्तावेज़ या परेशानी टिकट पा सकते हैं जो प्रदर्शन के मुद्दे का वर्णन करता है कि यह ऑड-ईवन कोड ठीक करने वाला है। फिर अपने बदलाव करने के बाद, प्रदर्शन परीक्षण फिर से चलाएँ। यदि यह बहुत अलग नहीं है, या अभी भी स्वीकार्य मापदंडों के भीतर है, तो यह शायद ठीक है।

ऐसा कभी-कभी हो सकता है कि जब सिस्टम के अन्य हिस्से बदलते हैं, तो इस प्रदर्शन-अनुकूलित कोड को अब इस तरह के भारी अनुकूलन की आवश्यकता नहीं है, लेकिन कठोर परीक्षण के बिना निश्चित रूप से यह जानने का कोई तरीका नहीं है।


1
जिन लोगों के साथ मैं काम करता हूं उनमें से एक को उन क्षेत्रों में चीजों को अनुकूलित करना पसंद है जो उपयोगकर्ता महीने में एक बार हिट करते हैं, अगर ऐसा अक्सर होता है। इसमें समय लगता है और बार-बार अन्य समस्याओं का कारण बनता है क्योंकि वह कोड-एंड-कमिटमेंट को पसंद करता है, और क्यूए या अन्य डाउनस्ट्रीम फ़ंक्शन को वास्तव में परीक्षण करने देता है। : / निष्पक्ष होने के लिए, वह आम तौर पर तेज, त्वरित और सटीक है, लेकिन ये पेनी-एंटे "अनुकूलन" बस बाकी टीम के लिए चीजों को कठिन बनाते हैं और उनकी स्थायी मौतें एक अच्छी बात होगी।
डेव

@ मूल्य: क्या ये अनुकूलन इसलिए लागू किए गए हैं या वास्तविक प्रदर्शन के मुद्दे हैं? या क्या यह डेवलपर सिर्फ इसलिए करता है क्योंकि वह कर सकता है? मुझे लगता है कि अगर आपको पता है कि अनुकूलन का कोई प्रभाव नहीं पड़ने वाला है, तो आप उन्हें सुरक्षित रूप से अधिक पठनीय कोड के साथ बदल सकते हैं, लेकिन मैं केवल उस व्यक्ति पर भरोसा करूंगा जो ऐसा करने के लिए सिस्टम का विशेषज्ञ है।
FrustratedWithFormsDesigner

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

@DaveE: मुझे लगता है कि मैं आपके साथ काम करने वाले आदमी के साथ अधिक सहमत हूं। अगर मुझे सामान को ठीक करने की अनुमति नहीं है जो कि बिना किसी अच्छे कारण के धीमा है , तो मैं पागल हो जाऊंगा। अगर मुझे C ++ की एक पंक्ति दिखाई देती है जो बार-बार स्ट्रिंग को इकट्ठा करने के लिए + ऑपरेटर का उपयोग करती है, या कोड जो खोलता है और हर बार लूप के माध्यम से / dev / urandom पढ़ता है , क्योंकि कोई व्यक्ति झंडा लगाना भूल गया है, तो मैं इसे ठीक करता हूं। इस बारे में कट्टरपंथी होने के कारण मैं गति बनाए रखने में कामयाब रहा, जब अन्य लोगों ने इसे एक बार में एक माइक्रोसेकंड स्लाइड करने दिया।
ज़ेन लिंक्स

1
खैर, हम असहमत होने के लिए सहमत होने जा रहे हैं। एक फ़ंक्शन के लिए रनटाइम पर आंशिक सेकंड बचाने के लिए कुछ घंटे बदलने से जो वास्तव में कभी-कभी निष्पादित होता है और कोड को अन्य डेवलपर्स के लिए सिर-खरोंच आकार में छोड़ना है ... सही नहीं है। यदि ये ऐसे कार्य थे जो ऐप के उच्च-तनाव वाले हिस्सों में बार-बार निष्पादित होते हैं, तो ठीक और बांका। लेकिन यह ऐसा मामला नहीं है जिसका मैं वर्णन कर रहा हूं। यह वास्तव में कोई अन्य कारण के बजाय "मैं इस बात को बनाया है कि UserX सप्ताह में एक बार तेजी से तेजी से करता है" के लिए किसी अन्य कारण के लिए आभारी कोड है। इस बीच, हमारे पास ऐसे काम हैं जो करने की ज़रूरत है।
डेवई

2

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

और "दुबला," अपठनीय कोड हमेशा अनुकूलित नहीं होता है।

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


2

मैं पढ़ने योग्य कोड के साथ अनुकूलित कोड को कभी नहीं बदलूंगा क्योंकि मैं प्रदर्शन के साथ समझौता नहीं कर सकता हूं और मैं प्रत्येक अनुभाग में उचित टिप्पणी का उपयोग करने का विकल्प चुनूंगा ताकि कोई भी उस अनुकूलित अनुभाग में लागू तर्क को समझ सके जो दोनों समस्याओं को हल करेगा।

इसलिए, कोड अनुकूलित किया जाएगा + उचित टिप्पणी यह ​​पठनीय भी बना देगा।

नोट: आप उचित टिप्पणी की सहायता से एक अनुकूलित कोड बना सकते हैं, लेकिन आप पठनीय कोड को एक अनुकूलित नहीं बना सकते।


मैं इस दृष्टिकोण से थकेगा क्योंकि यह एक व्यक्ति है जो कोड को संपादित करता है और टिप्पणी को सिंक में रखने के लिए भूल जाता है। अचानक प्रत्येक बाद की समीक्षा यह सोचकर चली जाएगी कि यह वास्तव में Y करते हुए X प्रदर्शन करता है।
जॉन डी

2

यहाँ सरल कोड और अनुकूलित कोड के बीच अंतर देखने के लिए एक उदाहरण है: https://stackoverflow.com/a/11227902/920964

उत्तर के अंत की ओर वह सिर्फ प्रतिस्थापित करता है:

if (data[c] >= 128)
    sum += data[c];

साथ में:

int t = (data[c] - 128) >> 31;
sum += ~t & data[c];

निष्पक्ष होने के लिए मुझे इस बात का कोई अंदाजा नहीं है कि अगर बयान को बदल दिया गया है, लेकिन जैसा कि उत्तरदाता कहता है कि इसके कुछ बिटवाइज़ ऑपरेशन उसी परिणाम दे रहे हैं (मैं सिर्फ इसके लिए अपना शब्द लेने जा रहा हूं)

यह मूल समय के एक चौथाई से भी कम समय में निष्पादित होता है (11.54sec बनाम 2.5sec)


1

यहां मुख्य प्रश्न यह है: क्या अनुकूलन की आवश्यकता है?

यदि ऐसा है तो आप इसे धीमी, अधिक पठनीय कोड से बदल नहीं सकते। इसे और अधिक पठनीय बनाने के लिए आपको इसमें टिप्पणियों आदि को जोड़ना होगा।

यदि कोड को अनुकूलित नहीं करना है, तो यह (पठनीयता को प्रभावित करने के बिंदु पर) नहीं होना चाहिए और आप इसे अधिक पठनीय बनाने के लिए इसे फिर से कारक कर सकते हैं।

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


1

इस तरह से मैं चीजों को करता हूं: पहले मैं इसे पठनीय कोड में काम करता हूं, फिर मैं इसे ऑप्टिमाइज़ करता हूं। मैं मूल स्रोत रखता हूं और अपने अनुकूलन चरणों का दस्तावेजीकरण करता हूं।

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


0

IMHO पठनीयता अनुकूलित कोड की तुलना में अधिक महत्वपूर्ण है क्योंकि ज्यादातर मामलों में माइक्रो-ऑप्टिमाइज़ेशन इसके लायक नहीं है।

गैर-सूक्ष्म सूक्ष्‍म अनुकूलन के बारे में लेख :

हम में से अधिकांश के रूप में, मैं गैर-इंद्रिय सूक्ष्म-अनुकूलन के बारे में ब्लॉग पोस्ट पढ़ने के लिए थक गया हूं जैसे कि इको द्वारा प्रिंट की जगह, + $ i द्वारा $ i ++, या एकल उद्धरण द्वारा डबल उद्धरण। क्यों? क्योंकि 99.999999% समय, यह अप्रासंगिक है।

"प्रिंट" "इको" की तुलना में एक से अधिक ओपकोड का उपयोग करता है क्योंकि यह वास्तव में कुछ देता है। हम यह निष्कर्ष निकाल सकते हैं कि प्रतिध्वनि प्रिंट से तेज है। लेकिन एक opcode लागत कुछ भी नहीं, वास्तव में कुछ भी नहीं है।

मैंने एक ताजा वर्डप्रेस इंस्टालेशन पर कोशिश की है। स्क्रिप्ट मेरे लैपटॉप पर "बस त्रुटि" के साथ समाप्त होने से पहले रुक जाती है, लेकिन opcodes की संख्या पहले से ही 2.3 मिलियन से अधिक थी। पर्याप्त कथन।


0

अनुकूलन सापेक्ष है। उदाहरण के लिए:

BOOL सदस्यों के एक समूह के साथ एक वर्ग पर विचार करें:

// no nitpicking over BOOL vs bool allowed
class Pear {
 ...
 BOOL m_peeled;
 BOOL m_sliced;
 BOOL m_pitted;
 BOOL m_rotten;
 ...
};

आप BOOL फ़ील्ड को बिटफ़िल्ड में बदलने के लिए लुभा सकते हैं:

class Pear {
 ...
 BOOL m_peeled:1;
 BOOL m_sliced:1;
 BOOL m_pitted:1;
 BOOL m_rotten:1;
 ...
};

चूंकि एक BOOL को INT के रूप में टाइप किया जाता है (जो कि विंडोज प्लेटफॉर्म पर एक हस्ताक्षरित 32-बिट पूर्णांक है), यह सोलह बाइट्स लेता है और उन्हें एक में पैक करता है। यह एक 93% बचत है! उसके बारे में कौन शिकायत कर सकता है?

यह धारणा:

चूंकि एक BOOL को INT के रूप में टाइप किया जाता है (जो कि विंडोज प्लेटफॉर्म पर एक हस्ताक्षरित 32-बिट पूर्णांक है), यह सोलह बाइट्स लेता है और उन्हें एक में पैक करता है। यह एक 93% बचत है! उसके बारे में कौन शिकायत कर सकता है?

फलस्वरूप होता है:

एक एकल बिट क्षेत्र में एक BOOL को परिवर्तित करने से डेटा के तीन बाइट की बचत होती है, लेकिन जब सदस्य को एक गैर-स्थिर मान सौंपा जाता है, तो आपको कोड के आठ बाइट खर्च होते हैं। इसी तरह, मूल्य निकालना अधिक महंगा हो जाता है।

क्या हुआ करता था?

 push [ebx+01Ch]      ; m_sliced
 call _Something@4    ; Something(m_sliced);

हो जाता है

 mov  ecx, [ebx+01Ch] ; load bitfield value
 shl  ecx, 30         ; put bit at top
 sar  ecx, 31         ; move down and sign extend
 push ecx
 call _Something@4    ; Something(m_sliced);

बिटफील्ड संस्करण नौ बाइट्स से बड़ा है।

चलो बैठते हैं और कुछ अंकगणित करते हैं। मान लीजिए कि इनमें से प्रत्येक बिटफील्ड फ़ील्ड आपके कोड में छह बार, लिखने के लिए तीन बार और पढ़ने के लिए तीन बार एक्सेस किया गया है। कोड वृद्धि में लागत लगभग 100 बाइट्स है। यह बिल्कुल 102 बाइट्स नहीं होगा क्योंकि ऑप्टिमाइज़र कुछ कार्यों के लिए रजिस्टरों में पहले से ही मूल्यों का लाभ उठाने में सक्षम हो सकता है, और अतिरिक्त निर्देशों में कम रजिस्टर लचीलेपन के संदर्भ में छिपी लागत हो सकती है। वास्तविक अंतर अधिक हो सकता है, यह कम हो सकता है, लेकिन एक लिफाफे की गणना के लिए चलो इसे 100 कहते हैं। इस बीच, स्मृति बचत प्रति वर्ग 15 बाइट थी। इसलिए, विच्छेद बिंदु सात है। यदि आपका कार्यक्रम इस वर्ग के सात से कम उदाहरण बनाता है, तो कोड की लागत डेटा बचत से अधिक हो जाती है: आपकी मेमोरी ऑप्टिमाइज़ेशन मेमोरी डे-ऑप्टिमाइज़ेशन थी।

संदर्भ

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