2016-04-21 2 views
11

पर्ल पूर्ववर्ती सरणी की अनुमति देता है। हम उपयोग से पहले सरणी को प्रीलोकेट कर सकते हैं, फिर हम और तत्व जोड़ सकते हैं। उदाहरण के लिए, 50 सरणी सदस्यों को आवंटित करते हुए 51 वें सदस्य जोड़ते हैं, क्योंकि सरणी विस्तारणीय होती है। तो एक सरणी प्रदर्शन प्रदर्शन में सुधार करता है?पर्ल में किसी सरणी के लिए स्मृति को प्रीलोकेट करने का क्या उपयोग है?

उत्तर

13

इसकी वजह यह है कि कंप्यूटर में स्मृति को आवंटित किया जाता है। कंप्यूटर मेमोरी एक व्हाइटबोर्ड पर जगह की तरह है: इसकी अन्य स्मृति के संबंध में स्थिति है; और इसे स्थानांतरित नहीं किया जा सकता है, इसे कॉपी किया जाना चाहिए।

यदि आप एक छोटे सरणी यह ​​ऐसा दिख सकता है बनाते हैं:

@array = (1, 4, 8, 12, 19); 

allocate memory for @array 
______________________|    |______| a b c|__________ 

copy in the data 
______________________| 1 4 8 12 19|______| a b c|__________ 

_ आवंटित नहीं की गई स्मृति है। | आपके सरणी को आवंटित की गई सीमाओं को इंगित करता है। | a b c| कुछ अन्य सरणी है।

फिर यदि आप उस सरणी पर कुछ बार धक्का देते हैं, तो पर्ल को स्मृति को पुन: आवंटित करना होगा। इस मामले में यह स्मृति को पहले से ही आवंटित स्थान में बढ़ा सकता है।

push @array, 23, 42; 

grow the existing memory 
______________________| 1 4 8 12 19  | a b c|__________ 

add the new data 
______________________| 1 4 8 12 19 23 42| a b c|__________ 

अब क्या होता है यदि आप अधिक संख्या @array पर दबाते हैं? यह अब आपकी याददाश्त नहीं बढ़ा सकता है, रास्ते में एक और सरणी है। तो, बस एक व्हाइटबोर्ड की तरह, इसे पूरे सरणी को स्मृति के स्पष्ट हिस्से में कॉपी करना होगा।

push @array, 85, 99; 

Allocate a new chunk of memory 
|       | 1 4 8 12 19 23 42| a b c|__________ 

Copy the existing data 
| 1 4 8 12 19 23 42  | 1 4 8 12 19 23 42| a b c|__________ 

Deallocate the old memory 
| 1 4 8 12 19 23 42  |__1__4__8_12_19_23_42| a b c|__________ 

Add the new data 
| 1 4 8 12 19 23 42 85 99|__1__4__8_12_19_23_42| a b c|__________ 

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

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

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


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

दूसरी बात यह है कि यह शायद कुछ हद तक पुराना दृश्य है कि आधुनिक ऑपरेटिंग सिस्टम पर स्मृति आवंटन कैसे काम करता है ... हालांकि पर्ल कभी-कभी ओएस पर भरोसा नहीं करता है, तो यह कभी भी अपनी याददाश्त आवंटन करेगा। use Config; print $Config{usemymalloc} देखें। n इंगित करता है कि पर्ल ऑपरेटिंग सिस्टम की स्मृति आवंटन का उपयोग कर रहा है, y इंगित करता है कि यह पर्ल का उपयोग कर रहा है।

अंगूठे का नियम है: प्रीलाकेट न करें, यह शायद आपके समय और कंप्यूटर की स्मृति का अपशिष्ट है। हालांकि, यदि नीचे दी गई शर्तों में से सभी सत्य हैं, तो देखें कि प्रीलाओटिंग सहायता करता है या नहीं।

  • आप profiled और एक समस्या मिली।
  • आप इसे जोड़कर डेटा संरचना को बढ़ा रहे हैं।
  • आप निश्चित रूप से इसके न्यूनतम अंतिम आकार के लिए जानते हैं।
  • वह आकार "बड़ा" है।

बहस के लिए "बड़ा" क्या है और पर्ल, आपके ऑपरेटिंग सिस्टम, आपके हार्डवेयर और आपके प्रदर्शन सहनशीलता के आपके संस्करण पर निर्भर करता है।

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