इन दोनों में से कौन सा कोड 'बेहतर' है? एक स्थानीय चर या एक वर्ग चर बनाना?


11

Im अधिक खेल बना रहा है और अधिक बेवकूफ सवाल पूछ रहा है।

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

मैं सोच रहा था कि क्या कई स्थानीय चर पूरे करने के लिए लूप को धीमा कर देंगे (स्थानीय रूप से मेरा मतलब फ़ंक्शन के अंदर ही है और कक्षा के शीर्ष पर नहीं है - सही शब्द का उपयोग करके आशा im)।

यहाँ मेरा मतलब है, दो तरीके जिन्हें मैं करने की सोच रहा था:

public class Player : MonoBehaviour {

private void FixedUpdate()
{
    Rigidbody rb = GetComponent<Rigidbody>();

    float v = Input.GetAxis("Vertical");

    rb.AddForce(v * rb.transform.forward * Const.walkForce);
}
}

या ...

public class Player : MonoBehaviour {
Rigidbody rb;

private void Awake()
{
    rb = GetComponent<Rigidbody>();
}

private void FixedUpdate()
{
    float v = Input.GetAxis("Vertical");

    rb.AddForce(v * rb.transform.forward * Const.walkForce);
}
}

4
यह कोड समीक्षा एसई के लिए एक प्रश्न की तरह लगता है।
Orphevs

1
आप फ्लोट वीए क्लास प्रॉपर्टी भी बना सकते हैं।
चाड

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

कोड का एक स्निपेट 'एक कोड' नहीं है। 'कौन सा कोड बेहतर है' के बारे में पूछना आपको शौकिया की तरह दिखता है।
माइल्स राउत

1
मैं एक शौकिया हूँ इसलिए मेरे साथ ठीक है धन्यवाद मीलों
बिग टी लैरिटी

जवाबों:


25

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

ऐसा इसलिए है क्योंकि एक संकरा दायरा कोड में उन स्थानों की संख्या को कम कर देता है जहां आपको उस डेटा के बारे में कारण बताना चाहिए, और इस प्रकार उन स्थानों की संख्या को कम कर सकता है जो आपके बारे में गलत तरीके से हो सकते हैं (जिससे बग्स होते हैं)।

वास्तव में अकेले स्थानीय चर घोषित करना व्यावहारिक रूप से प्रदर्शन की चिंता का विषय नहीं है: वे सस्ते हैं, और आधुनिक कंपाइलर भी "एक्स्ट्रा" का अनुकूलन कर सकते हैं।

उनकी शुरुआत करना एक चिंता का विषय हो सकता है; आपके मामले में आपके कठोर शरीर को हर बार देखा जाता है GetComponent, जिसमें कुछ गैर-शून्य लागत होती है। यदि आप जानते हैं कि इस विशेष गेम ऑब्जेक्ट के लिए कठोर शरीर घटक नहीं बदलेगा , तो आप इसे एक बार देख सकते हैं और परिणाम को एक सदस्य चर में संग्रहीत कर सकते हैं और प्रति कॉल ओवरहेड के एक छोटे से बच सकते हैं।

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

इसलिए, संक्षेप में: सामान्य रूप से, चीजों को यथासंभव स्थानीय बनाने के लिए डिफ़ॉल्ट है, लेकिन इस मामले में यह संभवतः rbएक सदस्य बनाने के लिए उचित है ताकि आप एक बार में लुकअप प्रदर्शन कर सकें Awakeऔर हर FixedUpdateकॉल करने से बचें ।


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

1
@SuperMegaBroBro GetComponent है बहुत तेजी से - आप कठिन देखने तुलनीय गति है कि किसी भी तरह का बनाने दबाया जा चाहते हैं। जब तक आपके पास प्रदर्शन डेटा है जो यह सुझाव देता है कि यह एक समस्या है, "चीजों को स्थानीय रखें" दृष्टिकोण के साथ रहें। आप इसे बाद में हमेशा ऑप्टिमाइज़ कर सकते हैं। उत्तर देखें ।unity.com/questions/185164/… यह मत भूलो कि कैशिंग मुफ्त भी नहीं है - यदि आप GetComponentअपने खेल में हर एक को कैश करते हैं, तो यह शायद शुद्ध नुकसान होगा। का आकलन करें। पहचानें कि अनुकूलन कहाँ लायक हैं। एक महान खेल बनाने पर ध्यान दें :)
लुआं

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

बहुत बहुत धन्यवाद दोस्तों, विशेष रूप से Luaan के रूप में मैं उस 'कैशिंग' मुद्दे के बारे में सोच रहा था, जबकि मैंने मूल प्रश्न लिखा था (लेकिन मैं वास्तव में उस शब्द को नहीं जानता था)। मैं निश्चित रूप से यथासंभव 'स्थानीय' दृष्टिकोण अपनाऊंगा। हमेशा की तरह सभी महान मदद के लिए धन्यवाद।
बिग टी लैररिटी

2

जोश पेट्री का जवाब बहुत अच्छा है - यहाँ एक पूरक परिप्रेक्ष्य है।

जब आप कोड के साथ काम करते हैं, जिसे आप काफी अच्छी तरह से समझते हैं, तो आप वेरिएबल को उस स्थान पर ले जा सकते हैं जहां वे समझ में आते हैं।

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

यदि आप handस्थानीय रूप से घोषणा करते हैं तो बाद में आप एक ऐसी karateChopविधि जोड़ सकते हैं जिसके लिए हाथ भी चाहिए। यह तब होता है जब स्थानीय रूप से चर घोषित करना समस्याग्रस्त हो सकता है - क्योंकि जूनियर डेवलपर्स अक्सर घोषणा को कॉपी / पेस्ट करने के लिए वापस आते waveGoodbyeहैं और अब आपके पास एक ही अवधारणा दो स्थानों में स्थित है। handतब किसी भी परिवर्तन को दोनों स्थानों में संशोधित करने की आवश्यकता होती है और इस तरह एक चींटी बग पहाड़ी शुरू होती है ।

तो कुल,

  1. यदि आप अपनी घोषणा के स्थान पर आश्वस्त हैं, तो इसे उस स्थान पर ले जाएं जहां यह समझ में आता है।

  2. यदि आप आश्वस्त नहीं हैं, तो स्थानीय शुरुआत करें और जब आप कोड का पुन: उपयोग करते हैं, तो रिफ्लेक्टर सुनिश्चित करें।

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


2
स्वाभाविक रूप से ऑर्डर की गई चीजें भी, जैसे हर Personसदस्य के पास होना चाहिए hand अगर आवेदन में इसकी प्रासंगिकता है, तो कोड को बेहतर ढंग से समझने के लिए अक्सर अन्य डेवलपर्स (ज्यादातर आप 6 महीने बाद) की मदद करते हैं। इस मामले में, यह तर्क है कि Rigidbodyआपके सदस्य के रूप में आपके पास Playerऔर, मैं और अधिक कहता हूं, भले ही इसका मतलब खराब प्रदर्शन हो। वीडियो-गेम्स में जो विचार करने के लिए एक प्रासंगिक बिंदु है, लेकिन मुझे लगता है कि कोड में , स्पष्ट होना अक्सर अधिक महत्वपूर्ण होता है
अलसीदार

1
उत्कृष्ट उत्तर धन्यवाद दोस्तों। मैं एक सब-के-सब जानने की कोशिश नहीं कर रहा हूँ, लेकिन इन सभी जवाबों की फिर से पुष्टि की है, जो मैं पहले से सोच रहा था, इसलिए एक बार के लिए मैं बहुत खुश हूँ और अपने खेल में कुछ अच्छी प्रगति कर रहा हूँ। अभी मैं उचित एनिमेशन और सब कुछ के साथ एक 3 डी फुटबॉल गेम बना रहा हूं, असली स्ट्राइड्स बना रहा हूं: डी जल्द ही मुझे यहां मदद की ज़रूरत होगी कि इसे 2-प्लेयर कैसे बनाया जाए और मैं ऑनलाइन मुलरिटप्लेर कहने की हिम्मत करता हूं: डी में मजेदार लोग हैं और फिर से धन्यवाद!
बिग टी लारिटी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.