2008-08-24 16 views
182

मैं लगातार सुनता हूं कि कितना बुरा प्रतिबिंब उपयोग करना है। जबकि मैं आम तौर पर प्रतिबिंब से बचता हूं और शायद ही कभी ऐसी स्थितियों को ढूंढता हूं जहां इसके बिना मेरी समस्या को हल करना असंभव है, मैं सोच रहा था ....NET प्रतिबिंब कितना महंगा है?

उन लोगों के लिए जिन्होंने अनुप्रयोगों में प्रतिबिंब का उपयोग किया है, क्या आपने प्रदर्शन हिट को माप लिया है और, क्या यह वास्तव में है खराब?

+0

आप इस प्रश्न को भी देखना चाहते हैं। http://stackoverflow.com/questions/224232/what-is-the-cost-of-reflection – smaclell

+1

fastflect.codeplex.com पर एपीआई का उपयोग करें। यह गेटर्स/सेटर्स/इनवॉकर्स और कुछ अन्य सामानों के लिए 500x की तरह प्रतिबिंब बढ़ाएगा। स्रोत और जानकारी यह कैसे काम करती है, यह भी है यदि आपको इसे विस्तारित करने की आवश्यकता है। –

+2

2014 में यह जानकारी कैसे जांचती है? इन 4 वर्षों में कुछ भी बदल गया? – Arnthor

उत्तर

113

यह है। लेकिन यह उस पर निर्भर करता है कि आप क्या करने की कोशिश कर रहे हैं।

मैं गतिशील रूप से असेंबली लोड करने के लिए प्रतिबिंब का उपयोग करता हूं (प्लगइन्स) और इसका प्रदर्शन "जुर्माना" कोई समस्या नहीं है, क्योंकि ऑपरेशन कुछ ऐसा है जो मैं एप्लिकेशन के स्टार्टअप के दौरान करता हूं।

हालांकि, अगर आप प्रत्येक पर प्रतिबिंब कॉल के साथ नेस्टेड छोरों की एक श्रृंखला के अंदर दर्शाती कर रहे हैं, मैं कहेंगे आप के लिए आपरेशन "समय की एक जोड़ी" अपने कोड :)

फिर से मिलना चाहिए, प्रतिबिंब पूरी तरह से है स्वीकार्य है और आप इसके साथ कोई देरी या समस्या नहीं देखेंगे। यह एक बहुत ही शक्तिशाली तंत्र है और इसका उपयोग .NET द्वारा भी किया जाता है, इसलिए मुझे नहीं लगता कि आपको इसे क्यों प्रयास नहीं करना चाहिए।

+0

में है मैं कोशिश करने के लिए प्रतिबिंब का उपयोग कर रहा हूं, कोशिश करने के लिए त्रुटि को लॉग करने के लिए वर्तमान विधि का वर्ग नाम। मूल रूप से त्रुटि लॉगिंग करते समय फ़ंक्शन नाम को हार्डकोडिंग से बचने के लिए। क्या मुझे चिंता करने की जरूरत है? –

+0

@ संग्राम नाप, यह ठीक है –

+0

@ संग्राम संख्या, जब तक कि आपको लगातार त्रुटियों की आवश्यकता नहीं होती है, जो तब तक एक अलग समस्या होनी चाहिए :) –

3

सबकुछ के साथ, यह स्थिति का आकलन करने के बारे में है। DotNetNuke में FillObject नामक एक काफी कोर घटक है जो डैटरोज़ से ऑब्जेक्ट्स को पॉप्युलेट करने के लिए प्रतिबिंब का उपयोग करता है।

यह एक काफी आम परिदृश्य है और एमएसडीएन, Using Reflection to Bind Business Objects to ASP.NET Form Controls पर एक आलेख है जो प्रदर्शन समस्याओं को शामिल करता है।

प्रदर्शन एक तरफ, एक विशेष बात यह है कि मुझे उस विशेष परिदृश्य में प्रतिबिंब का उपयोग करने के बारे में पसंद नहीं है, यह एक त्वरित नज़र में कोड को समझने की क्षमता को कम करने के लिए प्रेरित करता है, क्योंकि जब आप विचार करते हैं तो मेरे लिए प्रयास के लायक नहीं लगता आप दृढ़ता से टाइप किए गए डेटासेट या LINQ to SQL जैसे कुछ के विपरीत संकलन समय सुरक्षा भी खो देते हैं।

3

प्रतिबिंब प्रदर्शन पर ध्यान देने योग्य प्रभाव डाल सकता है यदि आप लगातार ऑब्जेक्ट सृजन के लिए इसका उपयोग करते हैं। मैंने Composite UI Application Block पर आधारित एप्लिकेशन विकसित किया है जो प्रतिबिंब पर निर्भर है। प्रतिबिंब के माध्यम से वस्तुओं के निर्माण से संबंधित एक उल्लेखनीय प्रदर्शन गिरावट थी।

हालांकि ज्यादातर मामलों में प्रतिबिंब उपयोग के साथ कोई समस्या नहीं है। यदि आपकी एकमात्र आवश्यकता कुछ असेंबली का निरीक्षण करना है तो मैं Mono.Cecil की सिफारिश करता हूं जो बहुत lightweight and fast

5

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

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

137

अपनी बात The Performance of Everyday Things में, जेफ रिचटर दिखाता है कि प्रतिबिंब द्वारा विधि को कॉल करना लगभग 1000 गुना धीमा सामान्य रूप से कॉल करने से है।

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

+14

मैंने देवसवरी में भी भाग लिया है, और इन परिणामों के साथ .NET 3.5 के लिए सहमत हैं। .NET 4 के लिए Devscovery प्रदर्शन बेंचमार्क प्रोग्राम का पुनर्मूल्यांकन बड़े पैमाने पर सुधार दिखाता है! लागत धीमी गति से 100 गुना कम हो जाती है। टाइपफ() लुकअप के लिए प्रतिबिंब का उपयोग करना उचित 3.5 के लिए .NET 3.5 और .NET 4. –

9

यह इतना बुरा है कि आपको प्रदर्शन-महत्वपूर्ण कोड के लिए .NET पुस्तकालयों द्वारा आंतरिक रूप से किए गए प्रतिबिंब के बारे में चिंतित होना चाहिए।

निम्नलिखित उदाहरण अप्रचलित है - उस समय सच (2008), लेकिन बहुत पहले हाल ही में सीएलआर संस्करणों में तय किया गया था। सामान्य रूप से प्रतिबिंब अभी भी कुछ हद तक महंगा बात है, यद्यपि!

बिंदु में मामला: आपको उच्च प्रदर्शन कोड में लॉक (सी #)/सिंकलॉक (वीबी.नेट) कथन में "ऑब्जेक्ट" के रूप में घोषित सदस्य का कभी भी उपयोग नहीं करना चाहिए। क्यूं कर? चूंकि सीएलआर वैल्यू टाइप पर लॉक नहीं कर सकता है, जिसका मतलब है कि इसे रन-टाइम प्रतिबिंब प्रकार जांचना है ताकि यह देखने के लिए कि आपका ऑब्जेक्ट वास्तव में संदर्भ प्रकार के बजाय एक मान प्रकार है या नहीं।

+13

के बीच अपरिवर्तित है, प्रतिबिंब प्रकार की जांच तेज है। – Jimmy

+1

इस तरह के 'प्रदर्शन महत्वपूर्ण कोड' के लिए आप वास्तव में .NET का उपयोग शुरू कर रहे हैं? – Seph

+1

@ सेफ: .NET, संख्या के गतिशील/प्रतिबिंब भाग। लेकिन सामान्य सी #/नेट, क्यों नहीं?सी ++ बनाम सी # स्पीडअप अनुप्रयोग परत पर सीमांत हैं (सी ++ अभी भी गहन गणित दिनचर्या पर कुछ% तेज है)। और मुझे लगता है कि आप असेंबली का सुझाव नहीं दे रहे हैं ... – DeepSpace101

12

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

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

मेरा मुद्दा यह है कि सहकर्मियों के साथ बातचीत में मैंने कई बार ध्यान दिया है कि प्रतिबिंब का उपयोग रनटाइम संचालन करने के बजाए संकलन करने के लिए कोड को स्वत: उत्पन्न करने के लिए हो सकता है और यह अक्सर विचार करने योग्य है।

+0

यह देखते हुए कि विजुअल स्टूडियो में ऐसा उत्कृष्ट टेम्पलेट समर्थन है, यह मुझे एक नया शब्द सिखाए जाने के लिए कोड पीढ़ी – Sebastian

12

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

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

+5

+1 का उपयोग करने का एक व्यावहारिक तरीका है: एनाथेमा भी तर्कहीन डर का जिक्र करने के लिए। मुझे प्रोग्रामर डरते हैं जो तर्कहीन तरीके से डरते हैं - इससे पता चलता है कि वे वास्तव में नहीं जानते कि वे क्या कर रहे हैं और सिर्फ यह बताते हुए कि वे अन्य लोगों को क्या कहते हैं। * खांसी कार्गो पंथ खांसी * – bsneeze

+1

अहहह कार्गो कल्ट। अब जिज्ञासु इंसान का एक अच्छा उदाहरण है haviour। – Quibblesome

1

प्रतिबिंब आपके ऐप के प्रदर्शन को बहुत धीमा नहीं करता है। आप प्रतिबिंब का उपयोग न करके कुछ चीजें जल्दी कर सकते हैं, लेकिन अगर प्रतिबिंब कुछ कार्यक्षमता प्राप्त करने का सबसे आसान तरीका है, तो इसका उपयोग करें। आप हमेशा प्रतिबिंब से आप कोड को प्रतिबिंबित करते हैं यदि यह एक perf समस्या बन जाता है।

1

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

12

आप एक पाश में नहीं हैं, तो।

3

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

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

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

स्रोत के चारों ओर पोक करें और क्या किया जा रहा है पर एक नज़र डालें।

53

प्रतिबिंब प्रदर्शन कार्यान्वयन पर निर्भर करेगा (दोहराव वाले कॉल कैश किए जाने चाहिए उदाहरण: entity.GetType().GetProperty("PropName"))। चूंकि अधिकांश प्रतिबिंब मैं दिन-दर-दिन आधार पर देखता हूं, डेटा पाठकों या अन्य भंडार प्रकार संरचनाओं से इकाइयों को पॉप्युलेट करने के लिए उपयोग किया जाता है, इसलिए मैंने ऑब्जेक्ट गुणों को प्राप्त करने या सेट करने के लिए उपयोग किए जाने पर विशेष रूप से प्रतिबिंब पर प्रदर्शन को बेंचमार्क करने का निर्णय लिया है।

मैंने एक परीक्षण तैयार किया जो मुझे लगता है कि यह उचित है क्योंकि यह सभी दोहराने वाली कॉलों को कैश करता है और केवल वास्तविक सेटवैल्यू या गेटवाल्लू कॉल को कैश करता है। प्रदर्शन परीक्षण के लिए सभी स्रोत कोड बिटबकेट में हैं: https://bitbucket.org/grenade/accessortest। जांच का स्वागत है और प्रोत्साहित किया जाता है।

निष्कर्ष यह है कि यह व्यावहारिक नहीं है और यह डेटा पहुंच परत में प्रतिबिंब को हटाने के लिए ध्यान देने योग्य प्रदर्शन सुधार प्रदान नहीं करता है जो प्रतिबिंब कार्यान्वयन अच्छी तरह से किया जाता है जब एक समय में 100,000 से कम पंक्तियों को वापस कर रहा है ।

Graph of time (y) against number of entities populated(x)

ग्राफ़ के ऊपर मेरी छोटी बेंचमार्क के उत्पादन को दर्शाता है और पता चलता है कि तंत्र कि प्रतिबिंब मात, केवल 100,000 चक्र चिह्न के बाद इतना काफ़ी है। अधिकांश डीएएल केवल एक समय में कई सौ या शायद हजारों पंक्तियां लौटाते हैं और इन स्तरों पर प्रतिबिंब ठीक प्रदर्शन करता है।

+9

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

+0

@ ग्रेनेड, एकल पहुंच डीएएल के लिए अच्छी जानकारी। –

+0

@RobertKoritnik यह मानते हुए कि आपके सर्वर पर वेब विधियां असीमित नहीं हैं – Kurren

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