2010-07-22 15 views
10

मैं पाइथन स्क्रिप्ट है कि कुछ कार्यों के लिए कई कॉल कर चल रहा हूँ, कहते हैं कि एफ 1 (x) और एफ 2 (x), कि इस जैसे दिखते हैं:पायथन में स्थिर स्मृति: क्या लूप स्मृति में चर के नए उदाहरण बनाते हैं?

x = LoadData() 

for j in range(N): 
    y = F1(x[j]) 
    z[j] = F2(y) 

    del y 

SaveData(z) 

प्रदर्शन बहुत तेजी से अगर मैं रखना है "डेल वाई" लाइन। लेकिन मुझे समझ में नहीं आता कि यह सच क्यों है। अगर मैं "डेल वाई" का उपयोग नहीं करता, तो मैं जल्दी से राम से बाहर चला जाता हूं और वर्चुअल मेमोरी का सहारा लेना चाहता हूं, और सब कुछ क्रॉल में धीमा हो जाता है। अगर मैं "डेल वाई" का उपयोग करता हूं तो खरीदें, फिर मैं बार-बार फ्लशिंग कर रहा हूं और वाई के लिए स्मृति आवंटित कर रहा हूं। मैं क्या करना चाहता हूं कि y स्थिर स्थिर स्मृति के रूप में बैठे हैं, और प्रत्येक F1 (x) कॉल पर स्मृति का पुन: उपयोग करें। लेकिन मैं जो कह सकता हूं उससे, यह नहीं हो रहा है कि क्या हो रहा है।

इसके अलावा, यह सुनिश्चित नहीं है कि यह प्रासंगिक है, लेकिन मेरे डेटा में numpy arrays शामिल हैं।

+0

यह प्रश्न शायद मानता है कि वाई को पहली बार लूप के अंदर घोषित किया गया है, मुझे इसका उल्लेख करना चाहिए था। हालांकि सवाल के इस पहलू पर टिप्पणी करने के लिए स्वतंत्र महसूस करें! –

+3

यदि आपको स्पष्ट 'डेल वाई' पसंद नहीं है तो लूप बॉडी को फ़ंक्शन में निकालें। इस तरह लूप के अंदर पूरी तरह से स्कॉप्ड किए गए किसी भी चर को प्रत्येक पुनरावृत्ति के लिए स्वचालित रूप से साफ़ किया जाएगा। – Duncan

उत्तर

11

del y के बिना आपको दो गुना अधिक स्मृति की आवश्यकता हो सकती है। ऐसा इसलिए है क्योंकि लूप के माध्यम से प्रत्येक पास के लिए, yF1 के पिछले मान से जुड़ा हुआ है जबकि अगली गणना की जाती है।

एक बार F1 रिटर्न वाई उस नए मूल्य के लिए रिबाउंड है और पुराना F1 परिणाम जारी किया जा सकता है।

इसका मतलब यह होगा कि वस्तु F1 द्वारा लौटाए काफी स्मृति

पुनरावृत्तियों की पहली जोड़ी के लिए पाश unrolling इस

y = F1(x[0]) # F1(x[0]) is calculated, then y is bound to it 
z[j] = F2(y) 
y = F1(x[1]) # y is still bound to F1(x[0]) while F1(x[1]) is computed 
       # The memory for F1(X[0]) is finally freed when y is rebound 
z[j] = F2(y) 

del y का उपयोग कर कैसा दिखेगा के एक बहुत पर है एक अच्छा समाधान है, तो है यह आपके मामले में हो रहा है।

+0

सुनें - यह पूरी तरह से बताता है कि आपके पास 'del y' –

+1

धन्यवाद के साथ बेहतर प्रदर्शन क्यों है, यह वास्तव में क्या हो रहा है: डेल के बिना, मेरी मेमोरी उपयोग युगल, आभासी स्मृति में थोड़ा सा फैलता है (क्योंकि मेरी रैम होती है वाई के एक और दो उदाहरणों के बीच झूठ बोलना) और कम प्रदर्शन पर स्क्रिप्ट स्लॉग। मैं अब के लिए डेल समाधान के साथ रहूंगा; वाई के उदाहरण कब/कैसे बनाए जाते हैं, यह बताने के लिए फिर से धन्यवाद। –

0

N के बहुत बड़े मूल्यों के लिए स्मृति बचाने के लिए range के बजाय xrange का उपयोग करें। इसके अलावा आप घोंसला कार्य कर सकते हैं लेकिन मुझे नहीं पता कि यह आपकी मदद करेगा या नहीं। : \

x = LoadData() 

for j in xrange(N): 
    z[j] = F2(F1(x[j])) 

SaveData(z) 

शायद F1 और F2 वस्तुओं की अनावश्यक प्रतियां बना रहे हैं, सबसे अच्छा तरीका है यथा-स्थान, कुछ की तरह:

x = LoadData() 
for item in x: 
    item.F1() 
    item.F2() 
SaveData(x) 

क्षमा करता है, तो जवाब देने के कर सकते हैं उपयोगी नहीं है

+0

मुझे चिंता है कि मेरा उदाहरण घोंसले की अनुमति देगा; यह वास्तविक लिपि में व्यावहारिक विकल्प नहीं है।मुझे लगता है कि gnibbler की प्रतिक्रिया सही ढंग से स्थिति का वर्णन करती है, लेकिन आपकी प्रतिक्रिया के लिए धन्यवाद। जब तक आपने इसे इंगित नहीं किया तब तक मैं xrange फ़ंक्शन से परिचित नहीं था। –

1

क्या आप वास्तव में चाहते हैं कुछ है कि अजगर में करने के लिए अजीब है है - आप y के लिए स्मृति का एक क्षेत्र का आवंटन और इसलिए यह है कि इस क्षेत्र का उपयोग कर सकते की अगली मूल्य का निर्माण करने के F1() है कि क्षेत्र के लिए सूचक पास करना चाहते हैं y। इससे बचने के F1() होने y के नए मूल्य के लिए खुद का आवंटन है करते हैं, संदर्भ तो अपने स्वयं के चर y में लिखा है जो करने के लिए

वहां पहले से ही है (जो वास्तव में, लेकिन जो कुछ भी F1() गणना का मूल्य इसे करने के लिए एक संदर्भ नहीं है) पायथन में संदर्भ द्वारा गुजरने के बारे में एक सवाल: How do I pass a variable by reference?

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