2012-01-08 6 views
7

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

(नोट: कृपया उस कोड के बारे में शिकायत न करें जिसने स्वयं को एसटीएल जैसे नहीं लिखा है, यह एक सी ++ अप्रबंधित कोड है, यह महत्वपूर्ण हिस्सा है)।

लेकिन प्रबंधित कोड में, जैसे कि जावा और सी # में कोड, आप प्रत्येक प्रक्रिया को नियंत्रित नहीं करते हैं, और स्मृति कुछ हद तक "छुपा" है, या आपके नियंत्रण में नहीं है। और यह कुछ अपेक्षाकृत अज्ञात प्रदर्शन करता है, ज्यादातर आप खराब प्रदर्शन से डरते हैं।

तो मेरा सवाल यह है कि: प्रबंधित कोड में एक अच्छा प्रदर्शन प्राप्त करने के लिए मुझे क्या समस्याएं और बोल्ड लाइन्स की देखभाल करनी चाहिए और ध्यान में रखना चाहिए?

मैं केवल इस तरह के रूप में कुछ प्रथाओं के बारे में सोच सकता है:

  • मुक्केबाजी और unboxing के बारे में पता होने के नाते।
  • सही संग्रह का चयन करना जो आपकी आवश्यकताओं को सर्वोत्तम रूप से सुइट करता है और सबसे कम ऑपरेशन लागत है।

लेकिन ये कभी भी पर्याप्त और भरोसेमंद नहीं लगते हैं! वास्तव में शायद मुझे उनका उल्लेख नहीं करना चाहिए था।

कृपया ध्यान दें कि मैं एक सी ++ वीएस सी # (या जावा) कोड की तुलना नहीं कर रहा हूं, मैंने समस्या की व्याख्या करने के लिए अभी सी ++ का उल्लेख किया है।

उत्तर

5

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

आप जीसी पर ध्यान केंद्रित कर रहे हैं; अब, कभी-कभी कोई समस्या हो सकती है, लेकिन आमतौर पर केवल विशिष्ट मामलों में; अधिकांश प्रणालियों के लिए पीढ़ी जीसी महान काम करता है।

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


दो बातें:

  • सुनिश्चित करें कि आप समझते हैं कि IDisposable और "का उपयोग" मतलब
  • छोरों में तार जोड़ नहीं है; द्रव्यमान सम्मेलन स्ट्रिंगबिल्डर
0

मैं बेहतर garbage collection एल्गोरिदम समझने का सुझाव दूंगा। आप उस मामले पर अच्छी किताबें पा सकते हैं, उदा। The Garbage Collection Handbook (रिचर्ड जोन्स, एंटनी होस्किंग, एलियट मॉस द्वारा)।

फिर, आपका प्रश्न व्यावहारिक रूप से विशेष कार्यान्वयन से संबंधित है, और शायद इसके विशिष्ट संस्करण तक भी। उदाहरण के लिए, Boehm's कचरा कलेक्टर का उपयोग करने के लिए प्रयुक्त (उदाहरण के लिए 2.4 में), लेकिन अब एक प्रतिलिपि बनाने वाला पीढ़ी का उपयोग करता है।

और यह न भूलें कि कुछ जीसी तकनीक उल्लेखनीय रूप से कुशल हो सकती हैं। एपेल का पुराना पेपर Garbage Collection can be faster than stack allocation याद रखें (लेकिन आज, कैश प्रदर्शन बहुत अधिक मायने रखता है, इसलिए विवरण अलग हैं)।

मुझे लगता है कि मुक्केबाजी (& अनबॉक्सिंग) से अवगत होना और आवंटन पर्याप्त है। कुछ कंपाइलर इन्हें अनुकूलित करने में सक्षम हैं (उनमें से कुछ से बचकर)।

यह मत भूलना कि जीसी प्रदर्शन व्यापक रूप से भिन्न हो सकता है। अच्छे जीसी (आपके आवेदन के लिए) और बुरे हैं।

और कुछ जीसी कार्यान्वयन काफी तेज़ हैं। उदाहरण के लिए Ocaml

में कोई भी मुझे परेशान नहीं करेगा: समयपूर्व अनुकूलन बुरा है।

(और सी ++ मेमोरी प्रबंधन, यहां तक ​​कि स्मार्ट पॉइंटर्स के साथ, या रेफ-काउंटर के साथ, अक्सर गरीब व्यक्ति की कचरा संग्रहण तकनीक के रूप में देखा जा सकता है; और आपके पास सी ++ क्या कर रहा है पर पूरा नियंत्रण नहीं है - जब तक आप फिर से नहीं ऑपरेटिंग सिस्टम विशिष्ट सिस्टम कॉल का उपयोग करके अपने ::operator new को कार्यान्वित करें-, इसलिए आप वास्तव में इसके प्रदर्शन को प्राथमिकता नहीं जानते हैं)

1

प्रबंधित भाषाओं के साथ प्रदर्शन के साथ ध्यान में रखना मुख्य बात यह है कि आपका कोड रनटाइम पर संरचना को बदल सकता है बेहतर अनुकूलित हो।

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

मैं यहां premature optimization के कानून का आह्वान करने जा रहा हूं और कहता हूं कि यदि पहले कोई समस्या बन जाती है, तो आपको पहले सही समाधान बनाना चाहिए, फिर वापस जाएं और अनुकूलित करने के प्रयास में वास्तव में धीमा गति से मापें।

+0

.NET हमेशा जेआईटी मूल कोड में सबकुछ संकलित करता है। और मुझे नहीं लगता कि यह सट्टा इनलाइनिंग, या पुनर्मूल्यांकन करता है। –

+0

@BenVoigt [इस उत्तर] के अनुसार (http://stackoverflow.com/questions/4043821/performance-differences-between-debug-and-release-builds/4045073#4045073) .NET JIT कंपाइलर कई संख्या करता है इन-लाइनिंग विधि सहित अनुकूलन। जिस बिंदु को मैं बना रहा था वह यह है कि प्रबंधित भाषाएं रनटाइम पर अनुकूलन या उपयोग किए जाने पर ऐसे अनुकूलन करने की क्षमता प्रदान करती हैं। – ahjmorton

+0

जब यह लक्ष्य स्थिर रूप से निर्धारित किया जा सकता है तो यह रेखांकित करता है। सट्टा इनलाइनिंग एक और अधिक उन्नत तकनीक है जो हॉटस्पॉट करता है और .NET नहीं करता है। –

4

बड़े अनुभवों का पुन: उपयोग करना मेरे अनुभव में बहुत महत्वपूर्ण है।

बड़े ऑब्जेक्ट ढेर पर ऑब्जेक्ट्स पूरी तरह से पीढ़ी 2 हैं, और इस प्रकार साफ करने के लिए एक पूर्ण जीसी की आवश्यकता होती है। और यह महंगा है।

+0

+1, इसे "ऑब्जेक्ट-पूलिंग" कहा जाता है :) – MattDavey

+1

मुझे लगता है कि यह कुछ (शायद सबसे अधिक) कार्यान्वयन के लिए सच है; लेकिन यह एक महत्वपूर्ण एक यद्यपि एक कार्यान्वयन विस्तार है। –

+0

@ बेसिलस्टारनकेविच यह बहुत सच है। एक गैर-पीढ़ी जीसी के लिए ऑब्जेक्ट पूलिंग वास्तव में ** प्रदर्शन ** गिरावट हो सकती है! – MattDavey

0

.NET जेनरिक संदर्भ प्रकारों पर विशेषज्ञ नहीं है, जो गंभीर रूप से सीमित करता है कि कितना इनलाइनिंग किया जा सकता है। यह (कुछ प्रदर्शन हॉटस्पॉट में) एक सामान्य कार्यान्वयन के पक्ष में एक सामान्य कंटेनर प्रकार से गुजरने के लिए समझ में आता है जिसे बेहतर अनुकूलित किया जाएगा। (नोट: इसका मतलब तत्व प्रकार object के साथ .NET 1.x कंटेनर का उपयोग करने का नहीं है)।

-1

आपको यह करना होगा: बड़ी वस्तुओं का उपयोग करके मेरे अनुभव में बहुत महत्वपूर्ण है।

बड़े ऑब्जेक्ट ढेर पर ऑब्जेक्ट्स पूरी तरह से पीढ़ी 2 हैं, और इस प्रकार साफ करने के लिए एक पूर्ण जीसी की आवश्यकता होती है। और यह महंगा है।

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

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