2009-05-06 9 views
5

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

फिर भी this पोस्ट में, एक्सएनए (गेम) प्लेटफार्म के डिजाइनर ने अपने मुख्य तर्क के रूप में एक इंटरफेस के खिलाफ अपने ढांचे के मुख्य वर्गों को डिजाइन नहीं किया है, जो कि एक प्रदर्शन हिट का संकेत देगा। यह एक खेल विकास के संदर्भ में है जहां हर एफपीएस संभवतः मायने रखता है, मुझे लगता है कि यह खुद से पूछने के लिए एक वैध सवाल है।

क्या किसी के पास कोई आंकड़ा है? मुझे इस तरह के गेम (ग्राफिक्स) ऑब्जेक्ट के साथ ध्यान में रखना चाहिए कि मुझे क्या पता नहीं होना चाहिए, इसका परीक्षण करने/मापने का एक अच्छा तरीका नहीं है।

+0

आपका प्रश्न अभी भी मान्य है लेकिन आप उस व्यक्ति को गलत तरीके से गलत कर रहे हैं। वह कह रहा है कि यूनिट परीक्षण के लिए केवल मोक्स प्रदान करने के लिए इंटरफेस प्रदान करना * प्रदर्शन हिट के लायक नहीं था। जो मैं उसका मुद्दा देख सकता हूं। –

+0

मुझे नहीं पता। एक पेर्फ हिट कितना काम करेगा?कुछ परीक्षण करने में सक्षम होने के लिए आप क्या लायक हैं? –

उत्तर

2

इंटरफेस आम तौर पर प्रदर्शन करने के लिए कुछ हिट मतलब (यह तथापि उपयोग की गई भाषा/क्रम के आधार पर बदल सकते हैं):

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

यहाँ एक चक्रीय ग्राफ जहां 2 इंटरफेस एक दूसरे के संदर्भ और न स्वचालित रूप से एकत्र किया जाएगा के रूप में उनके refcounts हमेशा से 1.

interface Parent { 
    Child c; 
} 

interface Child { 
    Parent p; 
} 

function createGraph() { 
    ... 
    Parent p = ParentFactory::CreateParent(); 
    Child c = ChildFactory::CreateChild(); 

    p.c = c; 
    c.p = p;  
    ... // do stuff here 

    // p has a reference to c and c has a reference to p. 
    // When the function goes out of scope and attempts to clean up the locals 
    // it will note that p has a refcount of 1 and c has a refcount of 1 so neither 
    // can be cleaned up (of course, this is depending on the language/runtime and 
    // if DAGS are allowed for interfaces). If you were to set c.p = null or 
    // p.c = null then the 2 interfaces will be released when the scope is cleaned up. 
} 
+0

हालांकि मैं इसे सब समझने का नाटक नहीं करूंगा, मुझे एक शिक्षित उत्तर दिखाई देता है। कुछ पुनर्चक्रण के लिए समय –

+0

क्या आप चक्रीय ग्राफ बनाने का उदाहरण दे सकते हैं? छद्म कोड शायद? –

+0

क्या जीसी जांच नहीं करता है कि क्या माता-पिता/बच्चे को रेफरी एक ऑब्जेक्ट है जो कचरा चेक के लिए भी चिह्नित है? लेकिन मैं देख सकता था कि इस तरह की जांच प्रदर्शन के लिए गहराई पर कितनी कठोर सीमा होगी। मुझे उस पर कठोर तथ्य नहीं हैं लेकिन मुझे विश्वास होगा कि .NET जीसी ऐसी चीज के लिए बचा होगा। –

0

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

+0

उतना विस्तार नहीं है (हालांकि मैं इसके लिए एक मामला बना सकता हूं) लेकिन टेस्टेबिलिटी मेरा मुख्य गोमांस है। कृपया http://stackoverflow.com/questions/804904/xna-mock-the-game-object/828482#828482 –

6

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

और जैसा कि पुराना मैक्सिम जाता है, एक तेज़ प्रोग्राम सही ढंग से चलाने के लिए एक सही प्रोग्राम चलाने के लिए तेज़ी से चलना आसान होता है।

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

+0

देखें लेकिन मुझे XNA ढांचे को डिज़ाइन नहीं किया गया है, इसलिए कोई इंटरफ़ेस उपलब्ध नहीं है .. –

+1

तो उस विशिष्ट मामले में आपके पास कोई विकल्प नहीं है, इसलिए कोई तुलना म्यूट है। – PaulJWilliams

+0

अधिकतम और ठोस सलाह – annakata

1

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

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

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

3

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

उचित कंपाइलर/जिट के साथ दूसरा मैं मानता हूं कि इंटरफ़ेस के साथ काम करने से कार्यान्वयन के खिलाफ काम करने की तुलना में अतिरिक्त समय की हास्यास्पद छोटी राशि होती है। इसके अलावा, टेम्पलेट्स जैसी तकनीकें इंटरफ़ेस कोड को चलने से हटा सकती हैं।

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

इसके अलावा मुझे लगता है कि यदि यह प्रदर्शन हिट सही था, तो अधिकांश गेम सी ++ के साथ ओओपी दृष्टिकोण का उपयोग नहीं करते थे, लेकिन ऐसा नहीं है, यह Article इसके बारे में कुछ बताता है।

सामान्य रूप में परीक्षणों के बारे में बात करना मुश्किल है, स्वाभाविक रूप से एक बुरा कार्यक्रम खराब इंटरफेस पर बहुत समय व्यतीत कर सकता है, लेकिन मुझे संदेह है कि यह सभी कार्यक्रमों के लिए सच है, तो आपको वास्तव में प्रत्येक विशेष कार्यक्रम को देखना चाहिए।

+3

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

3

What Things Cost in Managed Code

"वहाँ एक स्थिर कॉल, उदाहरण के कॉल, आभासी कॉल या इंटरफ़ेस कॉल के कच्चे लागत में एक महत्वपूर्ण अंतर होने के लिए प्रकट नहीं होता है।"

यह इस बात पर निर्भर करता है कि आपका कोड कितना रेखांकित होता है या संकलन समय पर नहीं, जो प्रदर्शन ~ 5x बढ़ा सकता है।

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

लेकिन चीजें करने का सही तरीका हमेशा लंबा लगता है।

+1

असल में मेरा मानना ​​है कि चीजें करने से सही तरीके से लंबे समय तक कम समय लगता है :)। –

+0

आपके लिए अच्छा है, लेकिन मेरी टिप्पणी पहली बार इसे बनाने के संदर्भ में थी, रखरखाव –

+0

नहीं, आप बिल्कुल सही हैं, मैं सहमत हूं। –

0

यह एक प्रदर्शन अर्थ होगा

डिजाइनर मारा अपनी राय साबित करने के लिए सक्षम होना चाहिए।

1
IMO

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

एक अंतरफलक के लिए कोडन: अभी तक मेरी राय में वहाँ एक व्यापक वैचारिक कारण है कि एक अंतरफलक के लिए कोडिंग का तात्पर्य (नहीं की गारंटी देता है) एक प्रदर्शन हिट पहुंच और बदलने के लिए।

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

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

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

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

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

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

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