comparison mercurial/statprof.py @ 40201:7df42042636d

py3: sprinkle statprof.py with utf-8 encoding Trying to chase the long tail of unicode badness in this file due to frame / code objects holding str everywhere. Differential Revision: https://phab.mercurial-scm.org/D5016
author Gregory Szorc <gregory.szorc@gmail.com>
date Fri, 12 Oct 2018 19:00:24 +0200
parents b594db74dc13
children 4613f9274fc0
comparison
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