अपने बड़े सॉफ्टवेयर प्रोजेक्ट में व्यवहार में जटिलता को कैसे मापें?


11

विश्वविद्यालय में, हमारे एल्गोरिदम पाठ्यक्रमों में, हम सीखते हैं कि अभ्यास में उपयोग किए जाने वाले विभिन्न सरल एल्गोरिदम की जटिलता की गणना कैसे करें, जैसे कि हैश टेबल या त्वरित सॉर्ट।

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

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

(क्योंकि मुझे यह दिखाने के लिए यह प्रतीत नहीं होता है कि यदि आप बड़ी संख्या में एल्गोरिदम का ढेर लगाते हैं, जो अपने आप बहुत तेजी से ज्ञात हैं, तो आप एक पूरे के रूप में एक तेज एप्लिकेशन के साथ समाप्त होते हैं।)

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


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

आपको बिंदु 1 में वर्णित इन परीक्षणों के लिए कुछ उपकरणों की आवश्यकता है
ओवरएक्सचेंज

1
बिग ओ विश्लेषण आपको यह नहीं बताता है कि एल्गोरिथ्म कैसे प्रदर्शन करेगा। यह आपको बताता है कि कैसे प्रदर्शन करेंगे पैमाने पर , के रूप में nबढ़ जाती है।
जॉन वू

जवाबों:


5

बड़े सॉफ्टवेयर प्रोजेक्ट में कई अलग-अलग घटक होते हैं, और उनमें से सभी आमतौर पर एक अड़चन नहीं होते हैं। इसके विपरीत: मेरे जीवन में लगभग किसी भी कार्यक्रम के लिए, जहां कम प्रदर्शन एक मुद्दा था, पेरेटो सिद्धांत ने लागू किया: 80% से अधिक प्रदर्शन लाभ कोड के 20% से कम का अनुकूलन करके प्राप्त किया जा सकता है (वास्तव में, मैं लगता है कि संख्या अक्सर 95% से 5% तक अधिक थी)।

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

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

विशिष्ट अनुकूलन तकनीकों में शामिल हैं

  • एल्गोरिदम और डेटा संरचनाओं के उपयोग में सुधार

  • पूर्व की ठीक ट्यूनिंग

  • कुछ वास्तविक गर्म स्थानों पर सूक्ष्म अनुकूलन

  • असेंबली कोड या CUDA का उपयोग करके महत्वपूर्ण अनुभागों को पुन: व्यवस्थित करना

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


13

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

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


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

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

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

@Wildcard, जबकि प्रदर्शन केवल रन टाइम पर मापा जा सकता है, यह सांख्यिकीय रूप से भविष्यवाणी की जा सकती है। डेटा संरचना का एक खराब विकल्प, प्रदर्शन परीक्षणों में, प्रदर्शन के लिहाज से ठीक-ठाक लग सकता है, लेकिन ऐसे किनारे के मामलों में बुरी तरह से विफल हो जाता है जिनकी भविष्यवाणी स्थैतिक विश्लेषण में की जा सकती है। यह वही कारण है जो हम सामान्य रूप से डेटा संरचनाओं के लिए सबसे खराब स्थिति जटिलता विश्लेषण को देखते हैं।
फ्रैंक हिलमैन

@Wildcard: आप सही हैं, हालांकि फ्रैंक भी बहुत सही है कि यह पोस्ट सवाल का जवाब नहीं देता है।
डॉक ब्राउन

3

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

मेरा पहला कदम एक विस्तृत आर्किटेक्चर आरेख पर अपने हाथों को प्राप्त करना या खुद को बनाना होगा। यह पता करें कि सॉफ्टवेयर में कौन से घटक हैं और प्रत्येक चरण में कितना समय लगता है।

इसके अलावा, यह पता लगाएं कि घटक एक-दूसरे के साथ कैसे बातचीत करते हैं। इससे सारा फर्क पड़ सकता है।

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

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

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