2010-07-30 10 views
26

मेरे पास एक ऐसा प्रोग्राम है जिसमें बड़ी संख्या में ऑब्जेक्ट्स हैं, उनमें से कई बेवकूफ सरणी हैं। मेरा प्रोग्राम बुरी तरह से स्वैप कर रहा है, और मैं स्मृति उपयोग को कम करने की कोशिश कर रहा हूं, क्योंकि यह वास्तव में वर्तमान मेमोरी आवश्यकताओं के साथ मेरे सिस्टम पर खत्म नहीं हो सकता है।पाइथन में प्रोफ़ाइल मेमोरी आवंटन (नम्पी सरणी के लिए समर्थन के साथ)

मैं एक अच्छा प्रोफाइलर ढूंढ रहा हूं जो मुझे विभिन्न वस्तुओं द्वारा उपभोग की गई स्मृति की मात्रा की जांच करने की अनुमति देगा (मैं एक स्मृति समकक्ष को cprrofile पर कल्पना कर रहा हूं) ताकि मुझे पता चले कि अनुकूलित करना कहां है।

मैंने हेपी के बारे में सभ्य चीजें सुनी हैं, लेकिन दुर्भाग्यवश दुर्भाग्य से नम्पी सरणी का समर्थन नहीं करता है, और मेरे अधिकांश कार्यक्रमों में नम्पी सरणी शामिल हैं।

+0

नहीं अपने (अच्छा) सवाल है, लेकिन आप निश्चित रूप से की dtype = np.float32/बहुत उपयोग कर सकते हैं। 64-बिट फ्लोट के बजाय 32-बिट के लिए Astype (np.float32)। (उन कार्यों से सावधान रहें जो चुपचाप 32 में करते हैं -> 64 आउट।) – denis

उत्तर

0

क्या आप उन्हें उपयोग नहीं करते समय tmp फ़ाइलों में डिस्क के कुछ सरणी को सहेज सकते हैं? अतीत में बड़े सरणी के साथ मुझे यही करना पड़ा। बेशक यह प्रोग्राम को धीमा कर देगा, लेकिन कम से कम यह खत्म हो जाएगा। जब तक आप उन्हें एक बार में जरूरत नहीं है?

+3

ठीक है, हाँ, लेकिन प्रोफाइलिंग का पूरा बिंदु यह है कि मैं यह जानना चाहता हूं कि * कौन सा सरणी मुझे फ़ाइल में लिखनी चाहिए। अगर मैं सब कुछ लिखने की कोशिश करता हूं और इसे केवल तब खींचता हूं जब मुझे इसकी आवश्यकता होती है, तो I/O आवश्यकताएं बहुत अधिक होंगी, और यह बिंदु को पराजित करेगी। – chimeracoder

10

memory profiler पर एक नज़र डालें। यह लाइन की रूपरेखा और Ipython एकीकरण है, जो यह बहुत आसान इसका इस्तेमाल करने के लिए बनाता है से लाइन प्रदान करता है: @WickedGrey ने उल्लेख किया

In [1]: import numpy as np 

In [2]: %memit np.zeros(1e7) 
maximum of 3: 70.847656 MB per loop 

अद्यतन

वहाँ एक बग हो रहा है (see github issue tracker) जब बुला एक समारोह एक से अधिक समय है, जो मैं पुन: पेश कर सकते हैं:

In [2]: for i in range(10): 
    ...:  %memit np.zeros(1e7) 
    ...:  
maximum of 1: 70.894531 MB per loop 
maximum of 1: 70.894531 MB per loop 
maximum of 1: 70.894531 MB per loop 
maximum of 1: 70.894531 MB per loop 
maximum of 1: 70.894531 MB per loop 
maximum of 1: 70.894531 MB per loop 
maximum of 1: 70.902344 MB per loop 
maximum of 1: 70.902344 MB per loop 
maximum of 1: 70.902344 MB per loop 
maximum of 1: 70.902344 MB per loop 

हालांकि मैं क्या परिणाम हो सकता है प्रभावित विस्तार करने के लिए पता नहीं है (है कि ज्यादा नहीं मेरे उदाहरण में है, तो लगता है डे आपके उपयोग के मामले में लंबित यह शायद अभी भी उपयोगी है) और जब यह समस्या ठीक हो सकती है। मैंने पूछा कि github पर।

+0

https://github.com/fabianp/memory_profiler/issues/9 ("फ़ंक्शन दो बार कॉल करते समय गलत परिणाम") ऐसा लगता है जैसे यह किसी भी गंभीर एप्लिकेशन के लिए गैर-स्टार्टर बनाता है। क्या मैं इस मुद्दे को गलत समझ रहा हूं? –

+0

@WickedGrey शायद आप सही हैं, मैंने पहले कभी 'memory_profiler' का उपयोग नहीं किया, बस इसके बारे में पढ़ें, लेकिन मैं अब इस बग को पुन: पेश कर सकता हूं। मेरा जवाब अपडेट किया गया। – bmu

+0

चूंकि memory_profiler ओएस को स्मृति की मात्रा का उपयोग करने के लिए पूछताछ करता है, इसलिए अलग-अलग रनों में थोड़ा अलग परिणाम होने की संभावना नहीं है क्योंकि यह आईपीथन इतिहास जैसी चीजों से दूषित हो सकता है या जिस तरह से पाइथन स्मृति आवंटित करता है (आप निश्चित रूप से कभी नहीं जानते जब उस स्मृति को जारी किया जाना है)। इसलिए, परिणामों में 1% से कम का अंतर मेरे लिए असंभव प्रतीत नहीं होता है। –

11

यदि आप कई अलग-अलग फ़ंक्शंस कॉल कर रहे हैं तो समस्या से निपटने का एक तरीका और आप अनिश्चित हैं कि स्वैपिंग कहां से आती है, memory_profiler से नई साजिश कार्यक्षमता का उपयोग करना होगा। सबसे पहले आपको @profile के साथ उपयोग किए जा रहे विभिन्न कार्यों को सजाने चाहिए। सादगी के लिए मैं उदाहरण examples/numpy_example.py memory_profiler के साथ भेज दिया कि दो कार्यों में शामिल है का उपयोग करेंगे: बजाय पायथन दुभाषिया के साथ इसे चलाने का अपनी स्क्रिप्ट चलाने के लिए, create_data() और process_data()

, आप mprof निष्पादन का उपयोग करें, कि

$ mprof run examples/numpy_example.py 
है

यह mprofile_??????????.dat नामक एक फ़ाइल तैयार करेगा, जहां? वर्तमान तारीख का प्रतिनिधित्व करने वाली संख्याएं रखेगी। परिणाम साजिश के लिए, बस टाइप mprof plot और यह एक साजिश इस के समान उत्पन्न होगा (आप कई .dat फ़ाइलें अगर यह हमेशा पिछले एक ले जाएगा):

output of memory_profiler's mprof

यहाँ आप स्मृति की खपत को देखते हैं, जब आप वर्तमान फ़ंक्शन को दर्ज/छोड़ते हैं तो इंगित करने वाले ब्रैकेट के साथ। इस तरह यह देखना आसान है कि फ़ंक्शन process_data() मेमोरी खपत का एक शीर्ष है। अपने फ़ंक्शन में आगे बढ़ने के लिए, आप अपने फ़ंक्शन में प्रत्येक पंक्ति की मेमोरी खपत देखने के लिए लाइन-बाय-लाइन प्रोफाइलर का उपयोग कर सकते हैं।यह

python -m memory_profiler examples/nump_example.py 

साथ चलाया जाता है यह आपको एक उत्पादन इस के समान देना होगा:

Line # Mem usage Increment Line Contents 
================================================ 
    13        @profile 
    14 223.414 MiB 0.000 MiB def process_data(data): 
    15 414.531 MiB 191.117 MiB  data = np.concatenate(data) 
    16 614.621 MiB 200.090 MiB  detrended = scipy.signal.detrend(data, axis=0) 
    17 614.621 MiB 0.000 MiB  return detrended 

जहां यह स्पष्ट है कि scipy.signal.detrend स्मृति की एक बड़ी राशि का आवंटन किया गया है।

0

क्या आपने massif उपकरण के साथ valgrind को आजमाया है?

valgrind --tool=massif python yourscript.py 

यह एक फ़ाइल पैदा करेगा massif.out.xxx कहा जाता है आप के माध्यम से

ms_print massif.out.xxx | less 

यह उपयोगी जानकारी के सभी प्रकार है निरीक्षण कर सकते हैं जो, लेकिन सही शुरुआत में भूखंड के लिए आप क्या देख रहे हैं होना चाहिए। Valgrind मुखपृष्ठ पर massif tutorial भी देखें।

valgrind का उपयोग करना काफी उन्नत है और आप जो भी खोज रहे हैं उसे करने के आसान तरीके हो सकते हैं।

1

numpy 1.7 के बाद से वहाँ एक अर्द्ध निर्मित रास्ता स्मृति आवंटन ट्रैक करने के लिए मौजूद है:

https://github.com/numpy/numpy/tree/master/tools/allocation_tracking

+1

पवित्र बकवास, यह बहुत उपयोगी है। धन्यवाद! मेरे पास एक ऐसा फ़ंक्शन था जिसका अधिकतम मेमोरी उपयोग 12x के कारक द्वारा अपने इनपुट डेटा के आकार के साथ स्केल कर रहा था। लेकिन अब, उस 'track_allocations.py' स्क्रिप्ट के लिए धन्यवाद, मैं इसे केवल 4x तक नीचे ला गया, इसलिए मैं उन अजीब' मेमोरी एरर 'को और नहीं देखूंगा। ओह! मेरे टूलबॉक्स में अब लवली है। –

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