2009-10-18 12 views
15

मैं एक उदाहरण विधि प्रोफ़ाइल कोशिश कर रहा हूँ का उपयोग कर, तो मैं कुछ ऐसा किया है, जबकि: पैदा होती है जब मैं "विधि" चाहते हैं कि गणना की जाती है एक मूल्य के वापस जाने के लिएवापसी मान cProfile

import cProfile 

class Test(): 

    def __init__(self): 
     pass 

    def method(self): 
     cProfile.runctx("self.method_actual()", globals(), locals()) 

    def method_actual(self): 
     print "Run" 

if __name__ == "__main__": 
    Test().method() 

लेकिन अब समस्याओं "method_actual" द्वारा। मैं वास्तव में दो बार "method_actual" को कॉल नहीं करना चाहता हूं।

क्या कोई और तरीका है, कुछ थ्रेड सुरक्षित हो सकता है? (अपने आवेदन में, cProfile डेटा आर्ग में से एक द्वारा नामित डाटाफाइलों में सहेजे जाते हैं, तो वे clobbered नहीं मिलता है और मैं उन्हें बाद में जोड़ सकते हैं।)

उत्तर

26

मुझे पता चला आप यह कर सकते हैं कि:

prof = cProfile.Profile() 
retval = prof.runcall(self.method_actual, *args, **kwargs) 
prof.dump_stats(datafn) 

नकारात्मकता यह है कि यह अनियंत्रित है।

+2

शानदार! यह सही दिखता है - लेकिन 'datafn' क्या है? –

+0

@ जोनाथन हार्टले - डेटा फ़ाइल आईआईआरसी के लिए फ़ाइल नाम। – detly

+0

आह, धन्यवाद। मैंने सोचा कि 'एफएन' का मतलब फ़ंक्शन है, फ़ाइल नाम नहीं। –

6

मैं एक ही समस्या से जूझ रहा था और प्रत्यक्ष वापसी मूल्यों को प्राप्त करने के लिए एक रैपर फ़ंक्शन का उपयोग करता था।

cP.runctx("a=foo()", globals(), locales()) 

के बजाय मैं एक आवरण समारोह

def wrapper(b): 
    b.append(foo()) 

बना सकते हैं और आवरण समारोह

b = [] 
cP.runctx("wrapper(b)", globals(), locals()) 
a = b[0] 

बाहर परम से foo कि गणना का परिणाम निकालने के लिए कॉल प्रोफ़ाइल (ख) बाद में ।

+0

एक आकर्षण की तरह काम करता है। –

18

किसी भी मनमाने ढंग से कोड के लिए एक विकल्प:

import cProfile, pstats, sys 
pr = cProfile.Profile() 
pr.enable() 

my_return_val = my_func(my_arg) 

pr.disable() 
ps = pstats.Stats(pr, stream=sys.stdout) 
ps.print_stats() 

https://docs.python.org/2/library/profile.html#profile.Profile

+0

आप 'contextlib's 'contextmanager' सजावट का उपयोग कर इसके लिए थोड़ा संदर्भ प्रबंधक भी बना सकते हैं। – detly

+0

मुझे 'रैंडम लिस्टिंग ऑर्डर का उपयोग किया गया था' - मैं लिस्टिंग ऑर्डर कैसे निर्दिष्ट कर सकता हूं? –

+1

पीएस।sort_stats ('संचयी') – marsh

1

से लिया मैं @detly लगता .runcall() मूल रूप से सबसे अच्छा जवाब है, लेकिन पूर्णता के लिए, मैं सिर्फ लेने के लिए '@ThomasH रों चाहता था

def wrapper(b, f, *myargs, **mykwargs): 
    try: 
     b.append(f(*myargs, **mykwargs)) 
    except TypeError: 
     print 'bad args passed to func.' 

# Example run 
def func(a, n): 
    return n*a + 1 

b = [] 
cProfile.runctx("wrapper(b, func, 3, n=1)", globals(), locals()) 
a = b[0] 
print 'a, ', a 
1

मैं एक डेकोरेटर बनाया:

समारोह स्वतंत्र होने के लिए जवाब देने के
import cProfile 
import functools 
import pstats 

def profile(func): 

    @functools.wraps(func) 
    def inner(*args, **kwargs): 
     profiler = cProfile.Profile() 
     profiler.enable() 
     try: 
      retval = func(*args, **kwargs) 
     finally: 
      profiler.disable() 
      with open('profile.out', 'w') as profile_file: 
       stats = pstats.Stats(profiler, stream=profile_file) 
       stats.print_stats() 
     return retval 

    return inner 

इसके साथ अपने कार्य या विधि डेकोरेट:

@profile 
def somefunc(...): 
    ... 

अब जब कि समारोह प्रोफाइल की जाएगी।

वैकल्पिक रूप से, अगर आप कच्चे, असंसाधित प्रोफ़ाइल डेटा चाहते हैं (उदाहरण के लिए, क्योंकि आप इसे पर उत्कृष्ट चित्रमय दर्शक RunSnakeRun चलाना चाहते हैं), तो:

import cProfile 
import functools 
import pstats 

def profile(func): 

    @functools.wraps(func) 
    def inner(*args, **kwargs): 
     profiler = cProfile.Profile() 
     profiler.enable() 
     try: 
      retval = func(*args, **kwargs) 
     finally: 
      profiler.disable() 
      profiler.dump_stats('profile.out') 
     return retval 

    return inner 

इस के कई पर एक छोटी सी सुधार है इस पृष्ठ पर अन्य उत्तरों।

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