2009-08-20 6 views
10

मुझे आश्चर्य है कि यह प्रदर्शन या स्मृति खपत को बहुत प्रभावित करता है। मुझे एक एनएसएमयूटेबलएरे की ज़रूरत है, और शुरुआत में मैं केवल अनुमान लगा सकता हूं कि कितनी वस्तुओं को जोड़ा जाएगा। लगभग 3 से 5 शायद। तो मैं इसे इस तरह बना देता हूं:यदि मैं क्षमता = 50 की बजाय क्षमता = 3 के साथ एनएसएमयूटेबलएरे बनाता हूं तो इससे कितना फर्क पड़ता है?

NSMutableArray *arr = [[NSMutableArray alloc] initWithCapacity:3]; 

उदाहरण के लिए 50 से अधिक की क्षमता के साथ इसे बनाने के दौरान, वास्तव में क्या होता है? क्या यह 1 की क्षमता के साथ बनाने का बुरा विचार होगा, जब यह जानकर कि कम से कम 20 तत्व होंगे? या क्या इससे कोई सिरदर्द लेने के लिए पर्याप्त कोई फर्क नहीं पड़ता? मुझे अपने ऐप में इनमें से 10 सरणी पसंद हैं और उन्हें सभी को शुरुआत में लोड करना होगा।

उत्तर

6

initWithCapacityNSMutableArray का कारण तत्वों की संख्या को पूर्वस्थापित करने के लिए कारण होगा।

उस क्षमता से परे अपने NSMutableArray में अधिक डेटा को धक्का देकर इसकी अंतर्निहित स्मृति को पुन: आवंटित करने के लिए NSMutableArray का कारण होगा। इस पुनर्वितरण को पूरे सरणी को पुराने (छोटे) आवंटन से नए (बड़े) में कॉपी करने की भी आवश्यकता होगी। तो इस नंबर को बहुत छोटा बनाने के लिए एक प्रदर्शन दंड है, लेकिन अधिकतर नहीं।

वास्तव में कचरे की स्मृति का उपयोग करने की तुलना में अधिक क्षमता निर्दिष्ट करना, क्योंकि उन वस्तुओं के लिए आवंटित स्मृति होगी जो कभी भी उपयोग नहीं की जाएगी।

मेरी सिफारिश यह होगी कि यदि आपको पता है कि आपके सरणी का आकार आम तौर पर एन आइटम से अधिक नहीं होगा, तो initWithCapacity:N पर कॉल करें। कभी-कभी NSMutableArray का प्रदर्शन दंड स्वीकार्य है, और यह एक जुर्माना है जिसे आपको उन सरणीओं के लिए भुगतान नहीं करना पड़ेगा जो उस सीमा पर नहीं जाते हैं।

+0

महान विवरण! अन्य उत्तरों भी महान थे। एक स्वीकार्य के रूप में इसे चुनना कभी मुश्किल नहीं पाया। सभी मतदान किया। सबको शुक्रीया! –

+2

सभी उचित सम्मान के साथ, मुझे लगता है कि यह उत्तर गलत है। यद्यपि क्षमता का उपयोग कुछ मामलों में संकेत देने के लिए किया जाता है, लेकिन ऐसा नहीं है कि एक गीगाबाइट की क्षमता वाले एक परिवर्तनीय सरणी बनाने से तुरंत स्मृति की गीगाबाइट आवंटित की जाएगी। यदि आप मुझ पर विश्वास नहीं करते हैं, तो इसे स्वयं आज़माएं। एनएसएमयूटेबलएरे * bigArray = [[NSMutableArray alloc] initWithCapacity: 1024 * 1024 * 1024]; अगर (! BigArray) { एनएसएलओजी (@ "ऐरे नहीं बनाया गया था!"); } अन्य { एनएसएलओजी (@ "हाँ, यह बनाया गया था।"); } यदि आप वास्तव में इस सरणी को भरते हैं, तो आपको स्मृति उपयोग में वृद्धि दिखाई देगी। इससे पहले नही। – peterb

+0

initWithCapacity के लिए प्रलेखन कहता है कि यह "आइटी आइटम्स ऑब्जेक्ट्स को पकड़ने के लिए पर्याप्त मेमोरी के साथ प्रारंभ की गई सरणी" देता है। क्या पीटरबर्ग ने देखा है और दस्तावेज के दावों के बीच कुछ विसंगति दिखाई देगी। – fbrereto

6

यह एक बड़ा सौदा नहीं है जब तक कि आप चरम पुनरावृत्ति या विशाल सरणी के बारे में बात नहीं कर रहे हों। ऑप्टिमाइज़ करने की कोशिश करने के लायक नहीं है जब तक कि यह वास्तविक बाधा बन जाए।

संपादित करें: मैं डोनाल्ड नुथ से एक उद्धरण जोड़ना चाहते हैं:

समय से पहले अनुकूलन सब बुराई की जड़ है।

+0

कि क्या समय से पहले बात मतलब है? मेरी अंग्रेजी इतनी महान नहीं है ;-) कृपया समझाएं। धन्यवाद! –

+2

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

+0

समझ में आता है :-) –

3

सैद्धांतिक उत्तर और व्यावहारिक उत्तर है। सिद्धांत रूप में, एक बड़ी क्षमता निर्धारित करने से सरणी के लिए आवंटन और संग्रहण रणनीति बदल सकती है (हालांकि आंतरिक रूप से संरचना "एनएसएआरएआरई" कहा जाता है, यह संरचना उससे थोड़ा अधिक जटिल है)।

एक व्यावहारिक दृष्टिकोण से, सरणी आवश्यकतानुसार पुन: आवंटित की जाएगी और जिन नंबरों के बारे में आप बात कर रहे हैं, मुझे संदेह है कि इसमें कोई अंतर होगा। मैं एक सरणी कर सकता हूं अगर मैं जानता था कि मैं हजारों वस्तुओं को हजारों में डाल दूंगा। 3 बनाम 50 अनिवार्य रूप से व्यर्थ है।

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

एक व्यावहारिक परिप्रेक्ष्य से, आपके समय का सबसे अच्छा उपयोग इस मुद्दे के बारे में भी सोचना नहीं है।

0

हालांकि यह निश्चित रूप से initWithCapacity: यहाँ उल्लेख दूसरों की तरह उपयोग करने के लिए कोई बुराई नहीं है तुम बाहर this research बार्तोज़ Ciechanowski से सरणी प्रारंभ प्रदर्शन पर जांच होनी चाहिए:

प्रारंभिक क्षमता लगभग कोई फर्क नहीं पड़ता

आइए प्रारंभिक क्षमता सेट के साथ नए एरे आवंटित करें:

for (int i = 0; i < 16; i++) { 
    NSLog(@"%@", [[[NSMutableArray alloc] initWithCapacity:1 << i] explored_description]); 
} 

आश्चर्य आश्चर्य:

size: 2 // requested capacity: 1 
size: 2 // requested capacity: 2 
size: 4 // requested capacity: 4 
size: 8 // requested capacity: 8 
size: 16 // requested capacity: 16 
size: 16 // requested capacity: 32 
size: 16 // requested capacity: 64 
size: 16 // requested capacity: 128 
... 
// 'size: 16' all the way down 
संबंधित मुद्दे