2010-06-15 7 views
9

मेरे कोड में, मैं बड़ी संख्या में कार्य करता हूं, प्रत्येक को डेटा को अस्थायी रूप से संग्रहीत करने के लिए स्मृति की एक बड़ी सरणी की आवश्यकता होती है। मेरे पास लगभग 500 कार्य हैं। प्रत्येक कार्य की शुरुआत में, मैं के लिए स्मृति को आबंटित एक सरणी: अबपुन: उपयोग करने वाले सरणी सी # में प्रदर्शन को इतना महत्वपूर्ण क्यों बढ़ाते हैं?

double[] tempDoubleArray = new double[M]; 

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

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

double[] tempDoubleArray = staticDoubleArray; 

हालांकि, मैं क्यों ठीक इस इतनी अच्छी तरह से काम करता है के अंधेरे में एक सा रहा हूँ। आईडी का कहना है कि मूल कोड में, जब tempDoubleArray गुंजाइश से बाहर हो जाता है, तो इसे एकत्र किया जा सकता है, इसलिए एक नई सरणी आवंटित करना मुश्किल नहीं होना चाहिए?

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

उत्तर

7

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

भालू। पुन: उपयोग करने वाले सरणी प्रदर्शन को बढ़ाने के लिए एक अच्छा बैंग-फॉर-बकाया तरीका है, हालांकि आपको बहुत सावधानीपूर्वक करना है।

स्पष्टीकरण के लिए, "चर बनाने वाले" द्वारा मेरा क्या मतलब है, विशेष रूप से उनके लिए जगह आवंटित करना और रनटाइम को जो भी कदम उठाने के लिए करना है (यानी मान को शून्य/शून्य में प्रारंभ करना)। चूंकि सरणी संदर्भ प्रकार हैं, वे ढेर पर संग्रहित होते हैं, जो स्मृति आवंटन की बात करते समय जीवन को थोड़ा और जटिल बना देता है। सरणी के आकार (चाहे कुल स्टोरेज स्पेस में 85 केबी से अधिक हो या नहीं) के आधार पर, यह या तो सामान्य ढेर या बड़े ऑब्जेक्ट हीप में संग्रहीत किया जाएगा। सामान्य ढेर पर संग्रहीत एक सरणी, जैसा कि अन्य सभी ढेर ऑब्जेक्ट्स के साथ, कचरा संग्रह और ढेर के संयोजन को ट्रिगर कर सकता है (जिसमें वर्तमान में उपयोग की जाने वाली जगह को अधिकतम करने के लिए वर्तमान में उपयोग में आने वाली स्मृति के आसपास घूमना शामिल है)। बड़े ऑब्जेक्ट हीप पर संग्रहीत एक सरणी कॉम्पैक्शन ट्रिगर नहीं करेगी (क्योंकि LOH कभी संकलित नहीं होता है), लेकिन यह स्मृति के एक और बड़े संगत ब्लॉक को लेकर समयपूर्व संग्रह को ट्रिगर कर सकता है।

+1

यह * नहीं * एन चर बना रहा है - यह केवल स्मृति का एक हिस्सा आवंटित कर रहा है और बिट्स को शून्य-आउट कर रहा है। उदाहरण के लिए सरणी निर्माण के दौरान कभी भी रचनाकारों को बुलाया नहीं जाता है। कोर i7 मेमोरी बैंडविड्थ के वास्तव में किसी न किसी अनुमान के आधार पर, आप उन 16 एमबी को 1 एमएमएस के क्रम में शून्य करने की उम्मीद करेंगे। –

+0

@EamonNerbonne: स्पष्ट होने के लिए, मैंने कहा कि यह चर बना रहा है (जो यह है), नहीं * उदाहरण *। –

+2

लेकिन आपको यह मानना ​​होगा कि यह कहना एक अजीब बात है। एक चर बनाने के लिए _mean_ क्या है? एक चर एक सार, संकलन-समय धारणा है जो रनटाइम पर स्वयं को कुछ भी नहीं करता है। –

1

एक जवाब हो सकता है large object heap - अधिक से अधिक वस्तुओं की तुलना में 85KB एक अलग LOH पर आवंटित किए जाते हैं, कि कम बार एकत्र और नहीं है जमा।

प्रदर्शन निहितार्थ से संबंधित अनुभाग देखें

  • आवंटन लागत (मुख्य रूप से आबंटित स्मृति बाहर समाशोधन)
  • संग्रह लागत (LOH और जेन 2 एक साथ एकत्र कर रहे हैं नहीं है - जेन 2 में बड़ी वस्तुओं के के कारण संघनन)
0

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

+0

वास्तव में वर्चुअल मेमोरी के उपयोग के कारण, संक्रामक ब्लॉक आवंटित करना कोई समस्या नहीं होनी चाहिए। – apoorv020

+0

मैं बिल्कुल स्पष्ट नहीं हूं कि वर्चुअल मेमोरी कैसे खेलती है। क्या सीएलआर अपने ही ढेर को बनाए रखता है?यदि ऐसा है, तो ओएस-स्तरीय मेमोरी पेजिंग शायद अप्रत्याशित मंदी के स्रोत से अधिक कुछ नहीं होगी। –

+0

उन्हें आभासी पता स्थान में संगत होने की आवश्यकता होगी, इसलिए विखंडन के मुद्दे अभी भी लागू हो सकते हैं। –

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