अनुकूलन समयपूर्व कब होता है?


82

जैसा कि नुथ ने कहा,

हमें छोटी क्षमताओं के बारे में भूलना चाहिए, समय के 97% के बारे में कहना चाहिए: समय से पहले अनुकूलन सभी बुराई की जड़ है।

यह एक ऐसी चीज है जो अक्सर स्टैक ओवरफ्लो के सवालों के जवाब में आती है जैसे "जो कि सबसे कुशल लूप तंत्र है", "एसक्यूएल अनुकूलन तकनीक?" ( और इसी तरह )। इन अनुकूलन-युक्तियों के सवालों का मानक उत्तर यह है कि आप अपने कोड को प्रोफाइल करें और देखें कि क्या यह पहली समस्या है, और यदि यह नहीं है, तो इसलिए आपकी नई तकनीक अनावश्यक है।

मेरा सवाल यह है कि यदि कोई विशेष तकनीक अलग है, लेकिन विशेष रूप से अस्पष्ट या अस्पष्ट नहीं है, तो क्या इसे वास्तव में समय से पहले का अनुकूलन माना जा सकता है?

यहाँ एक संबंधित लेख है रान्डेल हाइड ने जिसे द फॉलसी ऑफ़ प्रीमैच्योर ऑप्टिमाइज़ेशन कहा जाता है ।


42
यह एक विडंबना है कि बहुत से लोग जो "समय से पहले अनुकूलन" सभी बुराई की जड़ है "खुद को समय से पहले अनुकूलित किया है उद्धरण: (cont)
कुछ

22
"हमें छोटी क्षमताओं के बारे में भूलना चाहिए, 97% समय के बारे में कहना चाहिए: समय से पहले अनुकूलन सभी बुराई की जड़ है। फिर भी हमें उस महत्वपूर्ण 3% में अपने अवसरों को पारित नहीं करना चाहिए" (डोनाल्ड नथ)
कुछ

2
मुझे विश्वास है कि यह सीए होरे थे जिन्होंने यह कहा था। यहां तक ​​कि नुथ भी ऐसा कहते हैं।
15:22 बजे jamesh

1
हाँ, टोनी होरे ने पहली बार कहा था "समय से पहले अनुकूलन सभी बुरे हिस्से की जड़ है", लेकिन नथ ने उद्धृत किया / उसे आराम जोड़ते हुए कहा, मेरा मानना ​​है कि
निक डेफ

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

जवाबों:


103

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

अनुकूलन के नाम पर पेश किए गए कुछ मुहावरे इतने लोकप्रिय हो गए हैं कि हर कोई उन्हें समझता है और वे समय से पहले नहीं बल्कि उम्मीद बन गए हैं । उदाहरणों में शामिल

  • का उपयोग करते हुए सी में सरणी संकेतन के बजाय सूचक अंकगणितीय , जैसे कि मुहावरों का उपयोग करना

    for (p = q; p < lim; p++)
    
  • स्थानीय चर के लिए वैश्विक चर पुनर्पाठ , जैसे कि

    local table, io, string, math
        = table, io, string, math
    

ऐसे मुहावरों से परे, अपने जोखिम पर शॉर्टकट लें

जब तक सभी अनुकूलन समय से पहले हो

  • एक कार्यक्रम बहुत धीमा है (कई लोग इस हिस्से को भूल जाते हैं)।

  • आपके पास एक माप (प्रोफ़ाइल या समान) है जो दिखा रहा है अनुकूलन चीजों को बेहतर बना सकता है

(यह स्मृति के लिए अनुकूलन करने के लिए भी अनुमत है।)

प्रश्न का सीधा उत्तर:

  • यदि आपकी "अलग" तकनीक कार्यक्रम को समझने में कठिन बनाती है , तो यह समय से पहले का अनुकूलन है

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


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

1
@frankodwyer: लेकिन पॉइंटर को बढ़ाना संभवतः एक काउंटर को बढ़ाने और सरणी संकेतन का उपयोग करने की तुलना में तेज है, और यह समय से पहले अनुकूलन होगा।
जोआचिम सॉर

5
@ नोर्मन: हालांकि क्विकसॉर्ट अब सर्वव्यापी है, यह तब नहीं था जब पहली बार आविष्कार किया गया था, और इसलिए एक समय से पहले अनुकूलन किया गया था कि लेखक के साथ कोई खिलवाड़ नहीं था, है ना?
लॉरेंस डॉल

5
@ शेपर बंदर: बिल्कुल। सभी सीएस शोध करदाताओं के पैसे की बर्बादी है और इसे तुरंत रोक दिया जाना चाहिए।
नॉर्मन राम्से

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

40

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

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

इसलिए मेरी सलाह, अपनी आवश्यकताओं के आधार पर जल्दी से अनुकूलन करें, न कि आपका कोड, और आपके ऐप के संभावित विस्तारित जीवन को देखें।


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

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

@peterchen सिर्फ जिज्ञासा से बाहर है, आपने "पहले स्ट्रिंग चरित्र को हटाने" के लिए क्या किया होगा।
घोस 3t

1
@ user258365: जानवर बल एक स्ट्रिंग प्रतिनिधित्व का उपयोग करने के लिए होगा जिसे उप तारों के लिए एक प्रतिलिपि बनाने की आवश्यकता नहीं है। यह "लगभग तुच्छ" है जो अपरिवर्तनीय संदर्भ के लिए गिना जाता है। वैकल्पिक रूप से, एल्गोरिथम परिवर्तन, जैसे कि रिप्लेसिंग (स्यूडोकोड) while (s[0]==' ') s = s.substring(1) for(i=0; i<s.len && s[i]==' '; ++i); s=s.substring(i)--- लेकिन इसके लिए पहले से ही संभावित प्रदर्शन समस्याओं को जानना आवश्यक है (प्रोफाइलर्स यहां निरंतर सीखने के लिए मूल्यवान उपकरण हैं)।
पीटरचेन

@ ThorbjørnRavnAndersen, मैंने एक परियोजना को खत्म करने के लिए एक टीम की मदद करने के लिए एक सलाहकार के रूप में काम किया, फिर भी यह संभव नहीं था क्योंकि गंभीर प्रदर्शन मुद्दों की योजना नहीं बनाई गई (स्पेगेटी कोड के अलावा)। यह सभी रोगियों के इतिहास के साथ एक कालानुक्रमिक चार्ट दिखाना था। संपूर्ण डेटा के लिए एक अनुरोध किया गया था, जैसे कि Google मैप्स पूरी दुनिया को प्राप्त कर रहा है। खराब कोड का विकास, प्रोफाइलिंग की उम्मीद ने बाद में परियोजना को विफल कर दिया।
पेड्रो अमरल कोट्टो

31

यदि आपने प्रोफाइल नहीं बनाया है, तो यह समय से पहले है।


3
मैं इसके पीछे के विचार से सहमत हूं, लेकिन यह भी: जब तक कि कार्यान्वयन पूरी तरह से सीपीयू चक्रों से बाध्य नहीं होता है, तब तक माप प्राप्त करना जो दोनों पुन: प्रयोज्य हैं और सामान्यीकृत किया जा सकता है कठिन है - और यह जितना अधिक स्थिर है, उतना कम यथार्थवादी भी है।
पीटरचेन

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

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

@haslersn: "नुथ छोटी क्षमताओं के बारे में बात कर रहा था" डोनाल्ड नथ: "आज के सॉफ्टवेयर इंजीनियरों द्वारा साझा किए गए पारंपरिक ज्ञान छोटे में दक्षता को अनदेखा करने के लिए कहते हैं; लेकिन मेरा मानना ​​है कि यह केवल गालियों के लिए एक अतिशयोक्ति है ... (...) स्थापित इंजीनियरिंग एक 12% सुधार को आसानी से प्राप्त करता है, जिसे कभी भी सीमांत (...) नहीं माना जाता है
पेड्रो अमरल कोट्टो

27

मेरा सवाल यह है कि यदि कोई विशेष तकनीक अलग है, लेकिन विशेष रूप से अस्पष्ट या अस्पष्ट नहीं है, तो क्या इसे वास्तव में समय से पहले का अनुकूलन माना जा सकता है?

उम ... तो आपके पास दो तकनीकें तैयार हैं, लागत में समान (उपयोग करने, पढ़ने, संशोधित करने के लिए समान प्रयास) और एक अधिक कुशल है। नहीं, अधिक कुशल का उपयोग करने से उस स्थिति में, समय से पहले नहीं होगा।

आम प्रोग्रामिंग कंस्ट्रक्शन / लाइब्रेरी रूटीन के विकल्प की तलाश के लिए अपने कोड-राइटिंग को बाधित करना, मौका है कि एक और अधिक कुशल संस्करण कहीं न कहीं घूम रहा है, भले ही आप जो भी लिख रहे हैं उसकी सापेक्ष गति को जानते हुए भी आप वास्तव में कभी भी मायने नहीं रखेंगे। .. वह समय से पहले है।


3
सहमत, यदि आप जानते हैं कि एक एल्गोरिथ्म आपके उपयोग के मामले के लिए अधिक कुशल है, तो हर तरह से अधिक कुशल का उपयोग करें। यदि आप सबसे कुशल एल्गोरिथ्म को नहीं जानते हैं, तो आपके पास जो है, उसका उपयोग करें और बाद में देखें कि क्या यह एक समस्या है।
grepsedawk

10

यहाँ समस्या है जिसे मैं समय से पहले अनुकूलन से बचने की पूरी अवधारणा के साथ देखता हूं।

यह कहने और करने के बीच एक डिस्कनेक्ट है।

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

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

और शिक्षण सामग्री में जहां इन अमूर्त डिजाइन अवधारणाओं को पढ़ाया जाता है, जैसे कि अधिसूचना-संचालित वास्तुकला, और सूचना-छिपाना जहां बस किसी वस्तु की बूलियन संपत्ति स्थापित करना गतिविधियों का एक अनियंत्रित लहर प्रभाव हो सकता है, इसका कारण क्या है? दक्षता

तो, वह समय से पहले का अनुकूलन था या नहीं?


मुझे यह उत्तर पसंद है, क्योंकि यह अमूर्त और सामान्यीकरण के साथ प्रमुख समस्याओं में से एक को दिखाता है। जैसा कि आप उपयोग के मामलों की व्यापक श्रेणी का समर्थन करने के लिए एक वर्ग पदानुक्रम का सामान्यीकरण करते हैं, यह सबसे विशिष्ट उपयोग के मामलों के लिए प्रदर्शन को गंभीर रूप से बिगाड़ने के लिए बहुत आसान है। एक वर्ग पर कुंडी लगाना भी आसान है जो दिए गए कार्यक्षमता के स्वीकार्य स्तर के लिए कार्यक्षमता के स्वीकार्य स्तर पर प्रदान किए बिना जाँच के बिना कार्यक्षमता का एक टुकड़ा प्रदान करता है।
SmacL

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

8

सबसे पहले, काम कर कोड प्राप्त करें। दूसरा, सत्यापित करें कि कोड सही है। तीसरा, इसे जल्दी करो।

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


8

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


7

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

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

नुथ का यह भी कहना है कि अनुकूलन करने के बजाय, आपके प्रोग्राम का उपयोग करने वाले एल्गोरिदम को बदल दें, जिस दृष्टिकोण से यह समस्या होती है। उदाहरण के लिए जबकि थोड़ा ट्विकिंग आपको अनुकूलन के साथ गति में 10% की वृद्धि दे सकता है, मौलिक रूप से आपके कार्यक्रम के काम करने के तरीके को बदलकर इसे 10x तेज बना सकता है।

इस प्रश्न पर पोस्ट की गई बहुत सी अन्य टिप्पणियों की प्रतिक्रिया में: एल्गोरिथम चयन! = अनुकूलन


6

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

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


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

4

मैं केवल एक प्रदर्शन समस्या की पुष्टि होने पर अनुकूलन करने का प्रयास करता हूं।

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

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

मेरी सलाह: जब आप लाभ की मात्रा निर्धारित कर सकते हैं तो केवल अनुकूलन की लागत का भुगतान करने का प्रयास करें।


4

प्रोग्रामिंग करते समय, कई पैरामीटर महत्वपूर्ण होते हैं। इनमें से हैं:

  • पठनीयता
  • रख-रखाव
  • जटिलता
  • मजबूती
  • यथार्थता
  • प्रदर्शन
  • विकास का समय

अनुकूलन (प्रदर्शन के लिए जाना) अक्सर अन्य मापदंडों की कीमत पर आता है, और इन क्षेत्रों में "नुकसान" के खिलाफ संतुलित होना चाहिए।

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


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

3
इसे शुद्धता द्वारा कवर किया जा सकता है। इसके अलावा, 'जितना संभव हो उतनी तेजी से' के अर्थ में 'प्रदर्शन' आवश्यकताओं के बीच बहुत कम है, और यहां तक ​​कि ओला का यह कहना था कि अन्य जरूरतों के साथ एक व्यापार होना सच है।
फ्रैंकडॉयर

4

ऑप्टिमाइज़ेशन ग्रैन्युलैरिटी के विभिन्न स्तरों पर हो सकता है, बहुत उच्च-स्तर से बहुत निम्न-स्तर तक:

  1. एक अच्छी वास्तुकला, ढीली युग्मन, प्रतिरूपता आदि के साथ शुरू करें।

  2. समस्या के लिए सही डेटा संरचना और एल्गोरिदम चुनें।

  3. मेमोरी के लिए ऑप्टिमाइज़ करें, कैश में अधिक कोड / डेटा फिट करने की कोशिश कर रहा है। मेमोरी सबसिस्टम सीपीयू की तुलना में 10 से 100 गुना धीमा है, और यदि आपका डेटा डिस्क में पेजेड हो जाता है, तो यह 1000 से 10,000 गुना धीमा है। स्मृति खपत के बारे में सतर्क रहना व्यक्तिगत निर्देशों के अनुकूलन की तुलना में प्रमुख लाभ प्रदान करने की अधिक संभावना है।

  4. प्रत्येक फ़ंक्शन के भीतर, फ्लो-कंट्रोल स्टेटमेंट का उचित उपयोग करें। (लूप बॉडी के बाहर अपरिवर्तनीय अभिव्यक्तियों को स्थानांतरित करें। सबसे आम मान को पहले एक स्विच / केस आदि में डालें।)

  5. प्रत्येक कथन के भीतर, सही परिणाम देने वाले सबसे कुशल अभिव्यक्तियों का उपयोग करें। (बहु बनाम पारी, आदि)

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

और निश्चित रूप से, यदि आप एक लक्ष्य प्रदर्शन सीमा को परिभाषित नहीं करते हैं तो कोई भी अनुकूलन समय से पहले है।

ज्यादातर मामलों में, या तो:

ए) आप उच्च-स्तरीय अनुकूलन करके प्रदर्शन लक्ष्य सीमा तक पहुंच सकते हैं, इसलिए यह आवश्यक नहीं है कि अभिव्यक्ति के साथ बेला हो।

या

बी) सभी संभावित अनुकूलन करने के बाद भी, आप अपने लक्ष्य के प्रदर्शन की सीमा को पूरा नहीं करेंगे, और निम्न-स्तर की अनुकूलनशीलता पठनीयता के नुकसान को सही ठहराने के लिए प्रदर्शन में पर्याप्त अंतर नहीं लाती है।

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


3

नॉर्मन का जवाब बेहतरीन है। किसी तरह, आप नियमित रूप से कुछ "समय से पहले अनुकूलन" करते हैं, जो वास्तव में, सर्वोत्तम अभ्यास हैं, क्योंकि अन्यथा करना पूरी तरह से अक्षम माना जाता है।

उदाहरण के लिए, नॉर्मन की सूची में जोड़ने के लिए:

  • स्ट्रिंग + स्ट्रिंग (एक लूप में) के बजाय जावा (या सी #, आदि) में स्ट्रिंगब्यूटेन कंक्रीटिंग का उपयोग करना;
  • C की तरह लूप से बचना: for (i = 0; i < strlen(str); i++)(क्योंकि यहाँ strlen एक फ़ंक्शन कॉल है जो हर बार स्ट्रिंग पर चलती है, जिसे प्रत्येक लूप पर बुलाया जाता है);
  • यह अधिकांश जावास्क्रिप्ट कार्यान्वयनों में लगता है, यह करने के लिए तेज़ है for (i = 0 l = str.length; i < l; i++)और यह अभी भी पठनीय है, इसलिए ठीक है।

और इसी तरह। लेकिन ऐसे माइक्रो-ऑप्टिमाइज़ेशन कभी भी कोड की पठनीयता की कीमत पर नहीं आने चाहिए।


3

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

मुझे लगता है कि "समय से पहले अनुकूलन" अविश्वसनीय रूप से व्यक्तिपरक है।

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

Redesign शुरू से ही स्पष्ट तरीके से एक डिजाइन के अनुकूलन की तुलना में अधिक महंगा है।

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

इसलिए: एक डिजाइन का अनुकूलन नहीं है IMO एक कोड गंध है और अपने आप में।


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

2

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

[...] फिर से, यह समग्र चलने की गति में एक ध्यान देने योग्य बचत है, अगर, कहते हैं, n का औसत मूल्य लगभग 20 है, और यदि कार्यक्रम में खोज दिनचर्या लगभग एक मिलियन या इतनी बार की जाती है। ऐसे लूप ऑप्टिमाइज़ेशन [उपयोग करना gotos] सीखना मुश्किल नहीं है और, जैसा कि मैंने कहा है, वे एक कार्यक्रम के सिर्फ एक छोटे से हिस्से में उपयुक्त हैं, फिर भी वे अक्सर पर्याप्त बचत प्राप्त करते हैं। [...]

और जारी है:

आज के कई सॉफ्टवेयर इंजीनियरों द्वारा साझा किए गए पारंपरिक ज्ञान छोटे में दक्षता की अनदेखी करने के लिए कहते हैं; लेकिन मेरा मानना ​​है कि यह केवल उन दुर्व्यवहारों के लिए एक अतिशयोक्ति है जो वे पेनीवाइज़-एंड-पाउंड-मूर्ख प्रोग्रामर द्वारा अभ्यास किए जा रहे हैं, जो अपने "अनुकूलित" कार्यक्रमों को डिबग या बनाए नहीं रख सकते हैं। स्थापित इंजीनियरिंग में एक 12% सुधार आसानी से प्राप्त होता है, इसे कभी भी मामूली नहीं माना जाता है; और मेरा मानना ​​है कि सॉफ्टवेयर इंजीनियरिंग में समान दृष्टिकोण होना चाहिए। निश्चित रूप से मैं इस तरह के अनुकूलन को ऑनशॉट जॉब में परेशान नहीं करूंगा, लेकिन जब यह गुणवत्ता कार्यक्रमों को तैयार करने का सवाल है, तो मैं खुद को ऐसे टूल तक सीमित नहीं रखना चाहता जो मुझे इस तरह की क्षमता से वंचित करते हैं [अर्थात, goto इस संदर्भ में कथन]।

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

इसमें कोई संदेह नहीं है कि दक्षता की कब्र दुरुपयोग की ओर ले जाती है। प्रोग्रामर अपने कार्यक्रमों के गैर-महत्वपूर्ण हिस्सों की गति के बारे में सोचने या चिंता करने में बहुत समय बर्बाद करते हैं, और दक्षता पर इन प्रयासों का वास्तव में एक मजबूत नकारात्मक प्रभाव पड़ता है जब डिबगिंग और रखरखाव पर विचार किया जाता है। हमें छोटी दक्षता के बारे में भूल जाना चाहिए, समय का 97% कहना चाहिए; सभी बुराईयो की जड़ समयपूर्व इष्टतमीकरण है।

... और फिर प्रोफाइलिंग टूल्स के महत्व के बारे में कुछ और बातें:

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

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

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

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

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

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


1

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


1

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


1

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


0

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


0

जैसा कि मैंने एक समान प्रश्न पर पोस्ट किया था, अनुकूलन के नियम हैं:

1) अनुकूलन मत करो

2) (केवल विशेषज्ञों के लिए) बाद में ऑप्टिमाइज़ करें

अनुकूलन समयपूर्व कब होता है? आम तौर पर।

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

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

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

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

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