2011-01-20 11 views
15

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

उसने कहा, मुझे किसी दिए गए आकार में सरणी शुरू करने का कोई शानदार तरीका नहीं दिख रहा है, और मुझे नहीं पता कि क्यों। मैं जानता हूँ कि मैं कर सकते हैं:

my @array; $array[49] =0;

एक 50 आइटम सरणी प्राप्त करने के लिए, पर है कि वास्तव में मेरे लिए बदसूरत लग रहा है और मैं लगता है मानो वहाँ एक बेहतर तरीका होना चाहिए। विचार?

+2

कुछ भी नहीं गलत हैं यह व्यवस्था करने के लिए स्मृति लौटने के साथ मदद कर सकता है preallocating सरणी के साथ, लेकिन यह एक समयपूर्व और सूक्ष्म अनुकूलन की तरह गंध करता है। आपको लगता है कि 'पुश' ओ (एन) क्यों है? – mob

+0

अभी कोई लिंक ढूंढने का कोई समय नहीं है, लेकिन लंबी कहानी छोटी है: पुशिंग को अंतिम खुली जगह खोजने के लिए सरणी के माध्यम से लूपिंग की आवश्यकता होती है (वैसे भी जिस तरह से पुश आमतौर पर लागू किया जाता है, वैसे भी, हालांकि अब मैं इसके बारे में सोच रहा हूं, सामान्य रूप से सरणी की बजाय एक सिंगल लिंक्ड सूची के लिए)। क्या आप कह रहे हैं कि यह पर्ल में अलग-अलग लागू किया गया है? – Eli

+6

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

उत्तर

13

ईमानदार होने के लिए आपका तरीका बिल्कुल ठीक है, जैसा कि सरणी के आकार को स्पष्ट रूप से बदल रहा है: $#array = 49;;

+12

और यदि तत्वों को भी आरंभ करने की आवश्यकता है, तो 'my @ array = (0) x50' – slu

3

आपका रास्ता बहुत अच्छा है, और इसी तरह डीवीके है। इसे एक ही कमांड में करने का एक तरीका हो सकता है:

@array = (0 .. 49);

लेकिन मुझे यकीन है कि अगर यह, और अधिक सुरुचिपूर्ण है के बाद से यह प्रत्येक तत्व के लिए 1 और 49 के बीच कोई मान प्रदान करती है, लेकिन यह शायद बहुत ज्यादा नहीं पर्ल के वाक्य विन्यास में एक प्रोग्रामर के लिए समझने के लिए अधिक सहज है नहीं कर रहा हूँ।

+2

-1 का उपयोग करें आपका तरीका खराब है ... आप प्रीलोकेट नहीं कर रहे हैं, आप बस एक पंक्ति में 50 मान सेट करते हैं! – sebthebert

+3

@ सेबथबर्ट, यही वही है जो मैंने कहा था। कृपया कोड के नीचे भाग पढ़ें। – cbrandolino

5

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

for (my $loops = 0; $loops < 100000; $loops++) 
{ 
    my @arr; 

    for (my $foo = 0; $foo < 50; $foo++) { 
     push @arr, 'bar'; 
    } 
} 

2.13 यही कारण है कि सेकंड लिया।

for (my $loops = 0; $loops < 100000; $loops++) 
{ 
    my @arr; 
    $arr[49] = 0; 

    for (my $foo = 0; $foo < 50; $foo++) { 
     $arr[$foo] = 'bar'; 
    } 
} 

इसमें 2.16 सेकंड लगे (मैंने कई बार परीक्षण चलाया)। तो यह वास्तव में तेजी से होने के लिए समाप्त होता है ताकि सरणी को आवश्यकतानुसार आवंटित करने वाले पेर्ल हैंडल को चले। "पुश" विधि के लिए 2.27 सेकंड, और पूर्व आवंटन के लिए 2.21:

अद्यतन

ysth ने सुझाव दिया परिवर्तन करने के बाद, संख्या में थोड़ा और अधिक समझ बनाने के। फिर भी, मैं सवाल करता हूं कि क्या ऐसा अनुकूलन वास्तव में किसी भी समय बचाएगा (अंतर 100,000 पुनरावृत्तियों के बाद केवल 0.06 सेकंड था)।

+0

दिलचस्प! धन्यवाद! सिवाय मुझे यह नहीं मिलता कि यह कैसे संभव है ... – Eli

+0

@arr को एक पुनरावृत्ति से अगले पुन: उपयोग किया जाता है; बाहरी लूप के अंत में बाहरी लूप और '$ arrref = \ @ arr;' से पहले 'मेरा $ arrref;' कहने के लिए इसे लागू करने के लिए मजबूर करें। – ysth

+0

ने ysth के सुझाव को प्रतिबिंबित करने के लिए अपना उत्तर अपडेट किया। मुझे लगता है कि यह एक और अधिक उद्देश्य परिणाम प्राप्त करने का एक अच्छा तरीका है, लेकिन क्या ऐसी चीज वास्तविक दुनिया के उपयोग में की जाएगी? – Brian

11
  1. अनुकूलन क्लब का पहला नियम है, आप अनुकूलित नहीं करते हैं।
  2. ऑप्टिमाइज़ेशन क्लब का दूसरा नियम है, आप मापने के बिना अनुकूलित नहीं करते हैं।

मापने से पहले मापें, मापें, मापें और मान लें कि आप इसे पर्ल को बाहर निकालकर तेज़ी से कर सकते हैं। पर्ल सामान्य उपयोग के अनुकूलन को आपके पास बहुत लंबा कर रहा है। विशवास करो।

2
undef एक विशिष्ट मूल्य उपयोग करने के बजाय

my @array; 
$array[49] = undef; 
1

Preallocating गति के साथ ज्यादा मदद नहीं कर सकते हैं, लेकिन अगर हिस्सा आवंटित काफी बड़ा

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