##// END OF EJS Templates
statprof: use print function
Gregory Szorc -
r30257:7428223e default
parent child Browse files
Show More
@@ -102,7 +102,7 b" significantly off if other threads' work"
102 main thread's work patterns.
102 main thread's work patterns.
103 """
103 """
104 # no-check-code
104 # no-check-code
105 from __future__ import absolute_import, division
105 from __future__ import absolute_import, division, print_function
106
106
107 import collections
107 import collections
108 import contextlib
108 import contextlib
@@ -434,7 +434,7 b' def display(fp=None, format=3, **kwargs)'
434 import sys
434 import sys
435 fp = sys.stdout
435 fp = sys.stdout
436 if len(state.samples) == 0:
436 if len(state.samples) == 0:
437 print >> fp, ('No samples recorded.')
437 print('No samples recorded.', file=fp)
438 return
438 return
439
439
440 if format == DisplayFormats.ByLine:
440 if format == DisplayFormats.ByLine:
@@ -453,9 +453,9 b' def display(fp=None, format=3, **kwargs)'
453 raise Exception("Invalid display format")
453 raise Exception("Invalid display format")
454
454
455 if format != DisplayFormats.Json:
455 if format != DisplayFormats.Json:
456 print >> fp, ('---')
456 print('---', file=fp)
457 print >> fp, ('Sample count: %d' % len(state.samples))
457 print('Sample count: %d' % len(state.samples), file=fp)
458 print >> fp, ('Total time: %f seconds' % state.accumulated_time)
458 print('Total time: %f seconds' % state.accumulated_time, file=fp)
459
459
460 def display_by_line(fp):
460 def display_by_line(fp):
461 '''Print the profiler data with each sample line represented
461 '''Print the profiler data with each sample line represented
@@ -463,27 +463,28 b' def display_by_line(fp):'
463 stats = SiteStats.buildstats(state.samples)
463 stats = SiteStats.buildstats(state.samples)
464 stats.sort(reverse=True, key=lambda x: x.selfseconds())
464 stats.sort(reverse=True, key=lambda x: x.selfseconds())
465
465
466 print >> fp, ('%5.5s %10.10s %7.7s %-8.8s' %
466 print('%5.5s %10.10s %7.7s %-8.8s' %
467 ('% ', 'cumulative', 'self', ''))
467 ('% ', 'cumulative', 'self', ''), file=fp)
468 print >> fp, ('%5.5s %9.9s %8.8s %-8.8s' %
468 print('%5.5s %9.9s %8.8s %-8.8s' %
469 ("time", "seconds", "seconds", "name"))
469 ("time", "seconds", "seconds", "name"), file=fp)
470
470
471 for stat in stats:
471 for stat in stats:
472 site = stat.site
472 site = stat.site
473 sitelabel = '%s:%d:%s' % (site.filename(), site.lineno, site.function)
473 sitelabel = '%s:%d:%s' % (site.filename(), site.lineno, site.function)
474 print >> fp, ('%6.2f %9.2f %9.2f %s' % (stat.selfpercent(),
474 print('%6.2f %9.2f %9.2f %s' % (stat.selfpercent(),
475 stat.totalseconds(),
475 stat.totalseconds(),
476 stat.selfseconds(),
476 stat.selfseconds(),
477 sitelabel))
477 sitelabel),
478 file=fp)
478
479
479 def display_by_method(fp):
480 def display_by_method(fp):
480 '''Print the profiler data with each sample function represented
481 '''Print the profiler data with each sample function represented
481 as one row in a table. Important lines within that function are
482 as one row in a table. Important lines within that function are
482 output as nested rows. Sorted by self-time per line.'''
483 output as nested rows. Sorted by self-time per line.'''
483 print >> fp, ('%5.5s %10.10s %7.7s %-8.8s' %
484 print('%5.5s %10.10s %7.7s %-8.8s' %
484 ('% ', 'cumulative', 'self', ''))
485 ('% ', 'cumulative', 'self', ''), file=fp)
485 print >> fp, ('%5.5s %9.9s %8.8s %-8.8s' %
486 print('%5.5s %9.9s %8.8s %-8.8s' %
486 ("time", "seconds", "seconds", "name"))
487 ("time", "seconds", "seconds", "name"), file=fp)
487
488
488 stats = SiteStats.buildstats(state.samples)
489 stats = SiteStats.buildstats(state.samples)
489
490
@@ -514,10 +515,11 b' def display_by_method(fp):'
514 for function in functiondata:
515 for function in functiondata:
515 if function[3] < 0.05:
516 if function[3] < 0.05:
516 continue
517 continue
517 print >> fp, ('%6.2f %9.2f %9.2f %s' % (function[3], # total percent
518 print('%6.2f %9.2f %9.2f %s' % (function[3], # total percent
518 function[1], # total cum sec
519 function[1], # total cum sec
519 function[2], # total self sec
520 function[2], # total self sec
520 function[0])) # file:function
521 function[0]), # file:function
522 file=fp)
521 function[4].sort(reverse=True, key=lambda i: i.selfseconds())
523 function[4].sort(reverse=True, key=lambda i: i.selfseconds())
522 for stat in function[4]:
524 for stat in function[4]:
523 # only show line numbers for significant locations (>1% time spent)
525 # only show line numbers for significant locations (>1% time spent)
@@ -526,7 +528,7 b' def display_by_method(fp):'
526 stattuple = (stat.selfpercent(), stat.selfseconds(),
528 stattuple = (stat.selfpercent(), stat.selfseconds(),
527 stat.site.lineno, source)
529 stat.site.lineno, source)
528
530
529 print >> fp, ('%33.0f%% %6.2f line %s: %s' % (stattuple))
531 print('%33.0f%% %6.2f line %s: %s' % (stattuple), file=fp)
530
532
531 def display_about_method(fp, function=None, **kwargs):
533 def display_about_method(fp, function=None, **kwargs):
532 if function is None:
534 if function is None:
@@ -560,9 +562,9 b' def display_about_method(fp, function=No'
560 parents = [(parent, count) for parent, count in parents.iteritems()]
562 parents = [(parent, count) for parent, count in parents.iteritems()]
561 parents.sort(reverse=True, key=lambda x: x[1])
563 parents.sort(reverse=True, key=lambda x: x[1])
562 for parent, count in parents:
564 for parent, count in parents:
563 print >> fp, ('%6.2f%% %s:%s line %s: %s' %
565 print('%6.2f%% %s:%s line %s: %s' %
564 (count / relevant_samples * 100, parent.filename(),
566 (count / relevant_samples * 100, parent.filename(),
565 parent.function, parent.lineno, parent.getsource(50)))
567 parent.function, parent.lineno, parent.getsource(50)), file=fp)
566
568
567 stats = SiteStats.buildstats(state.samples)
569 stats = SiteStats.buildstats(state.samples)
568 stats = [s for s in stats
570 stats = [s for s in stats
@@ -579,7 +581,7 b' def display_about_method(fp, function=No'
579 total_self_percent += stat.selfpercent()
581 total_self_percent += stat.selfpercent()
580 total_cum_percent += stat.totalpercent()
582 total_cum_percent += stat.totalpercent()
581
583
582 print >> fp, (
584 print(
583 '\n %s:%s Total: %0.2fs (%0.2f%%) Self: %0.2fs (%0.2f%%)\n' %
585 '\n %s:%s Total: %0.2fs (%0.2f%%) Self: %0.2fs (%0.2f%%)\n' %
584 (
586 (
585 filename or '___',
587 filename or '___',
@@ -588,13 +590,14 b' def display_about_method(fp, function=No'
588 total_cum_percent,
590 total_cum_percent,
589 total_self_sec,
591 total_self_sec,
590 total_self_percent
592 total_self_percent
591 ))
593 ), file=fp)
592
594
593 children = [(child, count) for child, count in children.iteritems()]
595 children = [(child, count) for child, count in children.iteritems()]
594 children.sort(reverse=True, key=lambda x: x[1])
596 children.sort(reverse=True, key=lambda x: x[1])
595 for child, count in children:
597 for child, count in children:
596 print >> fp, (' %6.2f%% line %s: %s' %
598 print(' %6.2f%% line %s: %s' %
597 (count / relevant_samples * 100, child.lineno, child.getsource(50)))
599 (count / relevant_samples * 100, child.lineno,
600 child.getsource(50)), file=fp)
598
601
599 def display_hotpath(fp, limit=0.05, **kwargs):
602 def display_hotpath(fp, limit=0.05, **kwargs):
600 class HotNode(object):
603 class HotNode(object):
@@ -655,7 +658,7 b' def display_hotpath(fp, limit=0.05, **kw'
655 # Make frames that didn't actually perform work dark grey
658 # Make frames that didn't actually perform work dark grey
656 elif node.count - childrensamples == 0:
659 elif node.count - childrensamples == 0:
657 finalstring = '\033[90m' + finalstring + '\033[0m'
660 finalstring = '\033[90m' + finalstring + '\033[0m'
658 print >> fp, finalstring
661 print(finalstring, file=fp)
659
662
660 newdepth = depth
663 newdepth = depth
661 if len(visiblechildren) > 1 or multiple_siblings:
664 if len(visiblechildren) > 1 or multiple_siblings:
@@ -672,8 +675,9 b' def write_to_flame(fp, scriptpath=None, '
672 if scriptpath is None:
675 if scriptpath is None:
673 scriptpath = os.environ['HOME'] + '/flamegraph.pl'
676 scriptpath = os.environ['HOME'] + '/flamegraph.pl'
674 if not os.path.exists(scriptpath):
677 if not os.path.exists(scriptpath):
675 print >> fp, "error: missing %s" % scriptpath
678 print("error: missing %s" % scriptpath, file=fp)
676 print >> fp, "get it here: https://github.com/brendangregg/FlameGraph"
679 print("get it here: https://github.com/brendangregg/FlameGraph",
680 file=fp)
677 return
681 return
678
682
679 fd, path = tempfile.mkstemp()
683 fd, path = tempfile.mkstemp()
@@ -699,7 +703,7 b' def write_to_flame(fp, scriptpath=None, '
699 outputfile = '~/flamegraph.svg'
703 outputfile = '~/flamegraph.svg'
700
704
701 os.system("perl ~/flamegraph.pl %s > %s" % (path, outputfile))
705 os.system("perl ~/flamegraph.pl %s > %s" % (path, outputfile))
702 print "Written to %s" % outputfile
706 print("Written to %s" % outputfile, file=fp)
703
707
704 def write_to_json(fp):
708 def write_to_json(fp):
705 samples = []
709 samples = []
@@ -712,10 +716,10 b' def write_to_json(fp):'
712
716
713 samples.append((sample.time, stack))
717 samples.append((sample.time, stack))
714
718
715 print >> fp, json.dumps(samples)
719 print(json.dumps(samples), file=fp)
716
720
717 def printusage():
721 def printusage():
718 print """
722 print("""
719 The statprof command line allows you to inspect the last profile's results in
723 The statprof command line allows you to inspect the last profile's results in
720 the following forms:
724 the following forms:
721
725
@@ -732,7 +736,7 b' usage:'
732 flame [-s --script-path] [-o --output-file path]
736 flame [-s --script-path] [-o --output-file path]
733 Writes out a flamegraph to output-file (defaults to ~/flamegraph.svg)
737 Writes out a flamegraph to output-file (defaults to ~/flamegraph.svg)
734 Requires that ~/flamegraph.pl exist.
738 Requires that ~/flamegraph.pl exist.
735 (Specify alternate script path with --script-path.)"""
739 (Specify alternate script path with --script-path.)""")
736
740
737 def main(argv=None):
741 def main(argv=None):
738 if argv is None:
742 if argv is None:
@@ -767,7 +771,7 b' def main(argv=None):'
767 opts, args = getopt.getopt(sys.argv[optstart:], "hl:f:o:p:",
771 opts, args = getopt.getopt(sys.argv[optstart:], "hl:f:o:p:",
768 ["help", "limit=", "file=", "output-file=", "script-path="])
772 ["help", "limit=", "file=", "output-file=", "script-path="])
769 except getopt.error as msg:
773 except getopt.error as msg:
770 print msg
774 print(msg)
771 printusage()
775 printusage()
772 return 2
776 return 2
773
777
@@ -9,7 +9,6 b''
9 hgext/fsmonitor/pywatchman/capabilities.py not using absolute_import
9 hgext/fsmonitor/pywatchman/capabilities.py not using absolute_import
10 hgext/fsmonitor/pywatchman/pybser.py not using absolute_import
10 hgext/fsmonitor/pywatchman/pybser.py not using absolute_import
11 i18n/check-translation.py not using absolute_import
11 i18n/check-translation.py not using absolute_import
12 mercurial/statprof.py requires print_function
13 setup.py not using absolute_import
12 setup.py not using absolute_import
14 tests/test-demandimport.py not using absolute_import
13 tests/test-demandimport.py not using absolute_import
15
14
@@ -23,7 +22,7 b''
23 hgext/fsmonitor/watchmanclient.py: error importing: <ImportError> No module named 'pybser' (error at __init__.py:*)
22 hgext/fsmonitor/watchmanclient.py: error importing: <ImportError> No module named 'pybser' (error at __init__.py:*)
24 hgext/mq.py: error importing: <TypeError> __import__() argument 1 must be str, not bytes (error at extensions.py:*)
23 hgext/mq.py: error importing: <TypeError> __import__() argument 1 must be str, not bytes (error at extensions.py:*)
25 mercurial/scmwindows.py: error importing: <ImportError> No module named 'winreg' (error at scmwindows.py:*)
24 mercurial/scmwindows.py: error importing: <ImportError> No module named 'winreg' (error at scmwindows.py:*)
26 mercurial/statprof.py: invalid syntax: Missing parentheses in call to 'print' (<unknown>, line *)
25 mercurial/statprof.py: error importing: <TypeError> __slots__ items must be strings, not 'bytes' (error at statprof.py:*)
27 mercurial/win32.py: error importing: <ImportError> No module named 'msvcrt' (error at win32.py:*)
26 mercurial/win32.py: error importing: <ImportError> No module named 'msvcrt' (error at win32.py:*)
28 mercurial/windows.py: error importing: <ImportError> No module named 'msvcrt' (error at windows.py:*)
27 mercurial/windows.py: error importing: <ImportError> No module named 'msvcrt' (error at windows.py:*)
29
28
General Comments 0
You need to be logged in to leave comments. Login now