2008-10-14 11 views
27

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

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

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

+0

मुझे लगता है कि इस –

उत्तर

24

here से, प्रत्येक बार जब आप एक इंस्टेंस विधि कहते हैं तो एक स्थिर कॉल 4 से 5 गुना तेज होता है। हालांकि, हम अभी भी केवल कॉल के नैनोसेकंड के दसियों के बारे में बात कर रहे हैं, इसलिए आपको किसी भी लाभ का ध्यान देने की संभावना नहीं है जब तक कि आपके पास लाखों बार विधि को कॉल करने में वास्तव में तंग लूप नहीं होते हैं, और आप एक ही उदाहरण बनाकर समान लाभ प्राप्त कर सकते हैं वह लूप और इसका पुन: उपयोग कर रहा है।

चूंकि आपको नई स्थिर विधि का उपयोग करने के लिए हर कॉल साइट को बदलना होगा, तो संभवतः आप धीरे-धीरे रीफैक्टरिंग पर अपना समय बिता सकते हैं।

+0

बहुत बढ़िया लेख CS.SE के लिए चले जाना चाहिए। मैंने अभी ऐसा करना शुरू कर दिया क्योंकि मुझे तेज़ी से क्या दिलचस्पी थी। "ऑब्जेक्ट.read" या फॉर-लूप और आईएफ। और यह लेख मेरे व्यक्तिगत शोध के बाद ही एकदम सही बात है। बहुत अच्छा। अब मेरे पास एक बहुत बड़ी वस्तु है जिसे कई स्थानों पर पहुंचाया गया है और मैंने आश्चर्यचकित किया कि मौसम को उस विधि के तरीके से गुजरने के लायक है जिसकी जगह इसे जाना है या बस वैश्विक वैरिएबल क्लास बनाना है और वहां पहुंच सकते हैं। परीक्षण करने में कठोर क्या तेजी से होगा ...? :( –

2

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

वहां से आप धीरे-धीरे इन वस्तुओं के दायरे को छोटे और छोटे होने तक ले जा सकते हैं जब तक आपके पास एक सभ्य ओओपी डिज़ाइन न हो।

फिर फिर, दृष्टिकोण I शायद अलग है;)।

व्यक्तिगत रूप से, मैं उन संरचनाओं और कार्यों पर ध्यान केंद्रित करता हूं जो उन पर काम करते हैं और इन्हें छोटे से सदस्यों के साथ कक्षाओं में बदलने की कोशिश करते हैं।

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

3

मुझे लगता है कि आपने जिस तरीके से पूछा है उसमें आपने आंशिक रूप से इस प्रश्न का उत्तर दिया है: क्या आपके पास ध्यान देने योग्य आपके पास कोड में प्रदर्शन दंड है?

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

मुझे लगता है कि मैं जो कह रहा हूं वह है, एक प्रदर्शन समस्या केवल एक समस्या है जब आप देखते हैं कि यह एक समस्या है।

7

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

यह कहा गया है कि यह प्रदर्शन की तरह नहीं लगता है कि अभी आपकी सबसे बड़ी समस्या है।

9

मैंने एक ऐसी समस्या का सामना किया है जहां मैं काम करता हूं। मेरे सामने प्रोग्रामर ने 1 कंट्रोलर क्लास बनाया जहां सभी बीएलएल कार्यों को डंप किया गया।

हम अब सिस्टम को फिर से डिजाइन कर रहे हैं और कई नियंत्रक वर्ग बनाए हैं जो उन्हें नियंत्रित करने के लिए हैं।

UserController, GeographyController, ShoppingController ...

प्रत्येक नियंत्रक वर्ग वे स्थिर तरीकों जो कॉल कैश करने के लिए कर सकते हैं या दाल सिंगलटन पैटर्न का उपयोग कर के अंदर।

इसने हमें 2 मुख्य लाभ दिए हैं। यह थोड़ा तेज़ है (लगभग 2-3 गुना तेज लेकिन यहां नैनोसेकंड बात कर रहे थे; पी)। अन्य कि कोड अधिक स्वच्छ यानी

ShoppingController.ListPaymentMethods() 
बजाय

new ShoppingController().ListPaymentMethods() 

है मुझे लगता है कि यह भावना स्थिर तरीकों या वर्गों का उपयोग करने के अगर वर्ग किसी भी राज्य को बनाए रखने नहीं है बनाता है ।

5

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

जब आप इंटरफेस को लागू करने वाले वर्गों को परिभाषित करते हैं और आप उदाहरण विधियों को निष्पादित करते हैं तो यह नकली और/या नकली वस्तुओं के लिए बहुत सरल है। यह पूरी तरह से यूनिट परीक्षण त्वरित और प्रभावी बनाता है।

इसके अलावा, यदि आप अच्छे ओओ सिद्धांतों का पालन करना चाहते हैं (http://en.wikipedia.org/wiki/SOLID_%28object-oriented_design%29 पर सोलिड देखें) और/या डिज़ाइन पैटर्न का उपयोग करें, तो आप निश्चित रूप से बहुत से उदाहरण, इंटरफेस आधारित विकास, और कई स्थैतिक तरीकों का उपयोग नहीं करेंगे।

इस सुझाव के लिए के रूप में:

यह एक वस्तु बनाने के लिए जैसा कि आप एक तरीका है जिसके प्रतीत होता है वस्तु पर कोई साइड इफेक्ट है कॉल कर सकते हैं मेरे लिए मूर्खतापूर्ण लगता है (आपके वर्णन से मैं इस मान)।

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

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

2

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

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

ShapeUtils.DrawCircle(stroke, pen, origin, radius); 

ShapeUtils.DrawSquare(stroke, pen, x, y, width, length); 

वी.एस.

ShapeUtils utils = new ShapeUtils(stroke,pen); 

util.DrawCircle(origin,radius); 

util.DrawSquare(x,y,width,length); 

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

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

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

संबंधित मुद्दे