2010-08-24 9 views
6

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

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

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

मैं इसे स्वयं जांचता हूं, लेकिन किसी कारण से मेरे ऐप का प्रदर्शन रोलर कोस्टर की तरह ऊपर और नीचे जाता है और मुझे संदेह है कि मैं वास्तव में डेटा की कोई समझ नहीं कर पाऊंगा। मुझे आशा है कि कोई भी मेरे पूरे कोड को कुछ भी नहीं लिखने से पहले मेरी मदद कर सकता है :)

+1

आपको क्यों लगता है कि "स्थानीय चर का मतलब कचरा संग्रह" है? –

+0

क्योंकि जब वे दायरे से बाहर जाते हैं तो स्थानीय चर कचरा इकट्ठा होते हैं। – Crashworks

+0

और वैश्विक चर या तो ए हैं) कूलबेज एकत्रित होने पर एकत्र किया जाता है; या बी) स्मृति में रखा गया है, इस प्रकार उपयोग नहीं होने पर स्मृति दबाव को अनावश्यक रूप से बढ़ाया जाता है, अगर न्यूल पर सेट नहीं किया जाता है। –

उत्तर

8

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

यदि आपके ऐप को चलाने के दौरान आपके पास पर्याप्त प्रदर्शन परिवर्तनशीलता है, तो यह संभावना है कि स्थानीय चर के प्रदर्शन प्रभाव के बारे में आपका दावा असमान है।

सी में एक स्थानीय चर बनाने की "लागत" शून्य है; यह स्थानीय के लिए जगह बनाने के लिए बस एक रजिस्टर (ढेर सूचक) पर टक्कर लगी है। फिर आप उस चर को प्रारंभिक तरीके से प्रारंभ करते हैं। आपको यह जानना चाहिए कि क्या यह महंगा है या आकस्मिक निरीक्षण से नहीं। जब फ़ंक्शन निकलता है, तो स्टैक पॉइंटर को आपके पिछले मान पर वापस कर दिया जाता है, भले ही आपके पास कितने स्थानीय चर हैं।

यदि आपकी "स्थानीय चर" की परिभाषा ढेर आवंटित वस्तुओं है, हालांकि, आप स्मृति आवंटन की लागत से पीड़ित होंगे। मेमोरी आवंटन मेरी राय में बहुत धीमा है, इसलिए आप मॉलोक/फ्री (और जावा में 'नया') से दूर जाने के लिए जो कुछ भी कर सकते हैं, उतना ही बेहतर होगा। (मैं खेल बनाने के लिए, और हम dlmalloc का प्रयोग करते हैं लेकिन फिर भी है कि नियमित उपयोग के लिए बहुत धीमी है;। प्रति कॉल 400ns त्वरित कहते हैं)

+0

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

+0

स्थानीय पूर्णांक या अन्य आदिम डेटा प्रकारों को जावा में भी फैंसी कचरा संग्रह की आवश्यकता नहीं होनी चाहिए। –

11

Android के लिए, स्थानीय चर का मतलब है कचरा संग्रहण ...

यह एक गलत बयान है। स्थानीय चर ढेर पर आवंटित किए जाते हैं - गतिशील रूप से बाहर this article क्या आवंटित हो जाता है जहां जावा

एक नियम के रूप में, ढेर पर आवंटित आइटम कचरा संग्रहण की आवश्यकता होती है नहीं/मुक्त कराने और "मर" तुरंत पर heap.Check पर आवंटित नहीं निष्पादन के बाद इसके वर्तमान दायरे को छोड़ देता है। स्टैक आवंटन/डीलोकेशन महत्वपूर्ण ढेर आवंटन और कचरा संग्रहण से तेज़ है।

शैली और प्रदर्शन दोनों कारणों के लिए वैश्विक चर से बचने का प्रयास करें। स्टैक-आवंटित स्थानीय चर बहुत तेज प्रदर्शन करेंगे।

+0

जानना अच्छा है! चूंकि मैंने हमेशा कोशिश की, सभी वैश्विक बनाम सभी स्थानीय चर मुझे सभी वैश्विक दृष्टिकोण पर बेहतर प्रदर्शन मिला। मुख्य रूप से क्योंकि मैं बहुत सारी वस्तुओं और सरणी का उपयोग करता हूं। लेकिन अगर मैं आपको सही समझता हूं तो मैं सभी प्राचीन डेटा प्रकारों को स्थानीय छोड़ सकता हूं क्योंकि वे जीते हैं वैसे भी ढेर पर जाना नहीं है? – Pandoro

+0

+1 यह दुख की बात है कि बहुत सारे जावा प्रोग्रामर स्टैक और हीप आवंटन के बीच अंतर नहीं जानते हैं। लेकिन मुझे स्वीकार करना है, जब तक मैंने सी सी नहीं सी है, मैंने भी परेशान नहीं किया :-)। – helpermethod

+0

@ पांडोरो http://cslibrary.stanford.edu/102/PointersAndMemory.pdf देखें। यह भी एक असली आंख खोलने वाला था। – helpermethod

2

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

वस्तुओं को बनाने के साथ परफ के बारे में चिंता करने का एक स्थान यह है कि जब आप उन्हें ढेर पर आवंटित कर रहे हैं (उदाहरण के लिए malloc())। यह वही है जहां सी कचरा-एकत्रित भाषाओं की तुलना में "अधिक प्रदर्शनकारी" है, क्योंकि जब आप इन मॉलॉक्स होते हैं और जब वे मुक्त होते हैं तो आप वास्तव में देख और नियंत्रित कर सकते हैं। यह वास्तव में ऐसा नहीं है कि सी malloc() जावा new से तेज है; बल्कि, क्योंकि प्रत्येक आवंटन आपके लिए पारदर्शी और स्पष्ट है, आप यह सुनिश्चित करने के लिए आवश्यक कार्य कर सकते हैं कि इस तरह के धीमे संचालन जितना संभव हो उतना कम हो।

+0

सहमत हुए। वास्तव में, 'मॉलोक' आमतौर पर 'नए' की तुलना में बहुत धीमी होती है, और जीसी स्वीप कॉल की इसी संख्या की तुलना में अक्सर 'मुक्त' होती है। लेकिन विशेषज्ञ सी कोडर का उपयोग अंतर को बनाने के लिए स्मृति आवंटन के साथ पर्याप्त सावधानी बरतने के लिए किया जाता है (या अपने स्वयं के विशेष मेमोरी हैंडलिंग दिनचर्या लिखने के लिए जो उनके उपयोग के मामले में भी तेज़ होते हैं)। –

0

वैसे, एक सी फ़ंक्शन के भीतर एक परिवर्तनीय स्थैतिक घोषित करने से आपको वैश्विक नामस्थान को कूड़े बिना वैश्विक का व्यवहार मिल जाएगा।

लेकिन जैसा कि बताया गया है, स्टैक पर स्वचालित चर घोषित करने में 0 समय लगता है और उन चरों तक पहुंच भी बेहद तेज़ है, इसलिए फ़ंक्शन स्थानीय चर से बचने के लिए बहुत अधिक कारण नहीं है।

यदि आपको वास्तव में अनुकूलन के इस चरम स्तर की आवश्यकता है तो आपको कॉल ओवरहेड से बचने के लिए अपने सभी सामान्य कार्यों को इनलाइन करना चाहिए।

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