Python stats: how do I write it to a (human readable) file

后端 未结 5 1382
小蘑菇
小蘑菇 2021-02-07 00:39

I am using Python\'s hotshot profiler: http://docs.python.org/2/library/hotshot.html

It shows how to print the stats:

stats.print_stats(20)
相关标签:
5条回答
  • 2021-02-07 00:42

    stats.dump_stats(path/to/file)

    0 讨论(0)
  • 2021-02-07 00:47

    Stats takes an optional 'stream' argument. Simply open a file and pass the open file object to the Stats constructor as shown below. From that point any call to print_stats() will output to the stream you passed into the constructor. Hope this helps. :)

    with open('path/to/output', 'w') as stream:
        stats = pstats.Stats('path/to/input', stream=stream)
        stats.print_stats()
    
    0 讨论(0)
  • 2021-02-07 00:50

    How about output redirection?

    import sys
    import pstats
    sys.stdout = open('readable.profile', 'w')
    p = pstats.Stats('input.profile')
    p.print_stats()
    
    0 讨论(0)
  • 2021-02-07 00:57

    I ended up rewriting the print_stats() function, starting with copying it from pstats.py. It returns a string, which can then be written to a file. I have not tested every if-else loop, just that it works in the examples that I needed it for. I left the original lines commented out. I've left the variable names the same although it isn't really "self" that the function is using anymore.

    stats = hotshot.stats.load("stones.prof")
    stats.strip_dirs()
    stats.sort_stats('time', 'calls')
    readable_str = xprint_stats(stats, 20)
    
    import pstats
    def xprint_stats(self, *amount):
        x = ""
        for filename in self.files:
            x += " " + filename
        #if self.files: print >> self.stream
        # ?
        indent = ' ' * 8
        for func in self.top_level:
            #print >> self.stream, indent, xfunc_get_function_name(func)
            x += indent + pstats.func_get_function_name(func)
    
        #print >> self.stream, indent, self.total_calls, "function calls",
        x +=  indent + str(self.total_calls) + " function calls" + " "
        if self.total_calls != self.prim_calls:
            #print >> self.stream, "(%d primitive calls)" % self.prim_calls,
            x += "(%d primitive calls)" % self.prim_calls + " "
        #print >> self.stream, "in %.3f seconds" % self.total_tt
        #print >> self.stream
        x +=  "in %.3f seconds" % self.total_tt + "\n"
        #width, list = stats.get_print_list(amount)
        msg, width, list = xget_print_list(stats, amount)
        x += msg
    
        if list:
            #self.print_title()
            x += "\n" + '   ncalls  tottime  percall  cumtime  percall filename:lineno(function)'
            x += "\n"
            for func in list:
                #self.print_line(func)
                x +=  xprint_line(self, func) + "\n"
    #        print >> self.stream
    #        print >> self.stream
        #return self
        return x
    
    def xprint_line(self, func):  
        x = ""
        cc, nc, tt, ct, callers = self.stats[func]
        c = str(nc)
        if nc != cc:
            c = c + '/' + str(cc)
    #    print >> self.stream, c.rjust(9),
    #    print >> self.stream, f8(tt),
        x +=  c.rjust(9) + " "
        x +=  pstats.f8(tt) + " "
        if nc == 0:
            #print >> self.stream, ' '*8,
           x +=  ' '*8 
        else:
            #print >> self.stream, f8(float(tt)/nc),
            x +=  pstats.f8(float(tt)/nc) + " "
        #print >> self.stream, f8(ct),
        x +=  pstats.f8(ct) + " "
        if cc == 0:
            #print >> self.stream, ' '*8,
            x +=  ' '*8
        else:
            #print >> self.stream, f8(float(ct)/cc),
            x +=   pstats.f8(float(ct)/cc) + " "
        #print >> self.stream, func_std_string(func)
        x +=  pstats.func_std_string(func) + " "
        return x
    
    def xget_print_list(self, sel_list):
        width = self.max_name_len
        if self.fcn_list:
            stat_list = self.fcn_list[:]
            msg = "   Ordered by: " + self.sort_type + '\n'
        else:
            stat_list = self.stats.keys()
            msg = "   Random listing order was used\n"
    
        for selection in sel_list:
            stat_list, msg = self.eval_print_amount(selection, stat_list, msg)
    
        count = len(stat_list)
    
        if not stat_list:
            return 0, stat_list
        #print >> self.stream, msg
        if count < len(self.stats):
            width = 0
            for func in stat_list:
                if  len(pstats.func_std_string(func)) > width:
                    width = len(pstats.func_std_string(func))
        #return width+2, stat_list
        return msg, width+2, stat_list
    
    0 讨论(0)
  • 2021-02-07 00:59

    You can use the library: pstats_print2list https://pypi.python.org/pypi/pstats_print2list

    pip install pstats_print2list And usage:

    from pstats_print2list import get_pstats_print2list, print_pstats_list
    fname_stats = 'my_profiling_out.stats'
    pstats_list = get_pstats_print2list(
        os.path.expanduser(fname_stats),
        filter_fnames=['myfile1.py', 'myfile2.py', 'root_path1'],
        exclude_fnames=['dontshow.py', 'path_dont_show'],
        sort='cumulative',
        limit=5,
    )
    print_pstats_list(pstats_list)
    
    0 讨论(0)
提交回复
热议问题