mercurial/statprof.py
changeset 40201 7df42042636d
parent 40199 b594db74dc13
child 40381 4613f9274fc0
equal deleted inserted replaced
40200:9cc411952ab9 40201:7df42042636d
   360     with open(path, 'w+') as file:
   360     with open(path, 'w+') as file:
   361         file.write("%f %f\n" % state.accumulated_time)
   361         file.write("%f %f\n" % state.accumulated_time)
   362         for sample in state.samples:
   362         for sample in state.samples:
   363             time = sample.time
   363             time = sample.time
   364             stack = sample.stack
   364             stack = sample.stack
   365             sites = ['\1'.join([s.path, str(s.lineno), s.function])
   365             sites = ['\1'.join([s.path, b'%d' % s.lineno, s.function])
   366                      for s in stack]
   366                      for s in stack]
   367             file.write("%d\0%s\n" % (time, '\0'.join(sites)))
   367             file.write("%d\0%s\n" % (time, '\0'.join(sites)))
   368 
   368 
   369 def load_data(path):
   369 def load_data(path):
   370     lines = open(path, 'r').read().splitlines()
   370     lines = open(path, 'r').read().splitlines()
   505     fp.write(b'%5.5s  %9.9s  %8.8s  %-8.8s\n' % (
   505     fp.write(b'%5.5s  %9.9s  %8.8s  %-8.8s\n' % (
   506         b"time", b"seconds", b"seconds", b"name"))
   506         b"time", b"seconds", b"seconds", b"name"))
   507 
   507 
   508     for stat in stats:
   508     for stat in stats:
   509         site = stat.site
   509         site = stat.site
   510         sitelabel = '%s:%d:%s' % (site.filename(), site.lineno, site.function)
   510         sitelabel = '%s:%d:%s' % (pycompat.fsencode(site.filename()),
       
   511                                   site.lineno,
       
   512                                   pycompat.sysbytes(site.function))
   511         fp.write(b'%6.2f %9.2f %9.2f  %s\n' % (
   513         fp.write(b'%6.2f %9.2f %9.2f  %s\n' % (
   512             stat.selfpercent(), stat.totalseconds(),
   514             stat.selfpercent(), stat.totalseconds(),
   513             stat.selfseconds(), sitelabel))
   515             stat.selfseconds(), sitelabel))
   514 
   516 
   515 def display_by_method(data, fp):
   517 def display_by_method(data, fp):
   523 
   525 
   524     stats = SiteStats.buildstats(data.samples)
   526     stats = SiteStats.buildstats(data.samples)
   525 
   527 
   526     grouped = defaultdict(list)
   528     grouped = defaultdict(list)
   527     for stat in stats:
   529     for stat in stats:
   528         grouped[stat.site.filename() + ":" + stat.site.function].append(stat)
   530         grouped[stat.site.filename() + r":" + stat.site.function].append(stat)
   529 
   531 
   530     # compute sums for each function
   532     # compute sums for each function
   531     functiondata = []
   533     functiondata = []
   532     for fname, sitestats in grouped.iteritems():
   534     for fname, sitestats in grouped.iteritems():
   533         total_cum_sec = 0
   535         total_cum_sec = 0
   552             continue
   554             continue
   553         fp.write(b'%6.2f %9.2f %9.2f  %s\n' % (
   555         fp.write(b'%6.2f %9.2f %9.2f  %s\n' % (
   554             function[3], # total percent
   556             function[3], # total percent
   555             function[1], # total cum sec
   557             function[1], # total cum sec
   556             function[2], # total self sec
   558             function[2], # total self sec
   557             function[0])) # file:function
   559             pycompat.sysbytes(function[0]))) # file:function
   558 
   560 
   559         function[4].sort(reverse=True, key=lambda i: i.selfseconds())
   561         function[4].sort(reverse=True, key=lambda i: i.selfseconds())
   560         for stat in function[4]:
   562         for stat in function[4]:
   561             # only show line numbers for significant locations (>1% time spent)
   563             # only show line numbers for significant locations (>1% time spent)
   562             if stat.selfpercent() > 1:
   564             if stat.selfpercent() > 1:
   563                 source = stat.site.getsource(25)
   565                 source = stat.site.getsource(25)
       
   566                 if sys.version_info.major >= 3 and not isinstance(source, bytes):
       
   567                     source = pycompat.bytestr(source)
       
   568 
   564                 stattuple = (stat.selfpercent(), stat.selfseconds(),
   569                 stattuple = (stat.selfpercent(), stat.selfseconds(),
   565                              stat.site.lineno, source)
   570                              stat.site.lineno, source)
   566 
   571 
   567                 fp.write(b'%33.0f%% %6.2f   line %d: %s\n' % stattuple)
   572                 fp.write(b'%33.0f%% %6.2f   line %d: %s\n' % stattuple)
   568 
   573 
   597 
   602 
   598     parents = [(parent, count) for parent, count in parents.iteritems()]
   603     parents = [(parent, count) for parent, count in parents.iteritems()]
   599     parents.sort(reverse=True, key=lambda x: x[1])
   604     parents.sort(reverse=True, key=lambda x: x[1])
   600     for parent, count in parents:
   605     for parent, count in parents:
   601         fp.write(b'%6.2f%%   %s:%s   line %s: %s\n' %
   606         fp.write(b'%6.2f%%   %s:%s   line %s: %s\n' %
   602             (count / relevant_samples * 100, parent.filename(),
   607             (count / relevant_samples * 100,
   603             parent.function, parent.lineno, parent.getsource(50)))
   608              pycompat.fsencode(parent.filename()),
       
   609              pycompat.sysbytes(parent.function),
       
   610              parent.lineno,
       
   611              pycompat.sysbytes(parent.getsource(50))))
   604 
   612 
   605     stats = SiteStats.buildstats(data.samples)
   613     stats = SiteStats.buildstats(data.samples)
   606     stats = [s for s in stats
   614     stats = [s for s in stats
   607                if s.site.function == function and
   615                if s.site.function == function and
   608                (not filename or s.site.filename() == filename)]
   616                (not filename or s.site.filename() == filename)]
   618         total_cum_percent += stat.totalpercent()
   626         total_cum_percent += stat.totalpercent()
   619 
   627 
   620     fp.write(
   628     fp.write(
   621         b'\n    %s:%s    Total: %0.2fs (%0.2f%%)    Self: %0.2fs (%0.2f%%)\n\n'
   629         b'\n    %s:%s    Total: %0.2fs (%0.2f%%)    Self: %0.2fs (%0.2f%%)\n\n'
   622         % (
   630         % (
   623         filename or '___',
   631         pycompat.sysbytes(filename or '___'),
   624         function,
   632         pycompat.sysbytes(function),
   625         total_cum_sec,
   633         total_cum_sec,
   626         total_cum_percent,
   634         total_cum_percent,
   627         total_self_sec,
   635         total_self_sec,
   628         total_self_percent
   636         total_self_percent
   629         ))
   637         ))
   631     children = [(child, count) for child, count in children.iteritems()]
   639     children = [(child, count) for child, count in children.iteritems()]
   632     children.sort(reverse=True, key=lambda x: x[1])
   640     children.sort(reverse=True, key=lambda x: x[1])
   633     for child, count in children:
   641     for child, count in children:
   634         fp.write(b'        %6.2f%%   line %s: %s\n' %
   642         fp.write(b'        %6.2f%%   line %s: %s\n' %
   635               (count / relevant_samples * 100, child.lineno,
   643               (count / relevant_samples * 100, child.lineno,
   636                child.getsource(50)))
   644                pycompat.sysbytes(child.getsource(50))))
   637 
   645 
   638 def display_hotpath(data, fp, limit=0.05, **kwargs):
   646 def display_hotpath(data, fp, limit=0.05, **kwargs):
   639     class HotNode(object):
   647     class HotNode(object):
   640         def __init__(self, site):
   648         def __init__(self, site):
   641             self.site = site
   649             self.site = site