##// END OF EJS Templates
dispatch: add support for statprof as a profiler...
Bryan O'Sullivan -
r16392:ee3f423d default
parent child Browse files
Show More
@@ -687,14 +687,7 b' def _dispatch(req):'
687 if repo and repo != req.repo:
687 if repo and repo != req.repo:
688 repo.close()
688 repo.close()
689
689
690 def _runcommand(ui, options, cmd, cmdfunc):
690 def lsprofile(ui, func, fp):
691 def checkargs():
692 try:
693 return cmdfunc()
694 except error.SignatureError:
695 raise error.CommandError(cmd, _("invalid arguments"))
696
697 if options['profile']:
698 format = ui.config('profiling', 'format', default='text')
691 format = ui.config('profiling', 'format', default='text')
699 field = ui.config('profiling', 'sort', default='inlinetime')
692 field = ui.config('profiling', 'sort', default='inlinetime')
700 climit = ui.configint('profiling', 'nested', default=5)
693 climit = ui.configint('profiling', 'nested', default=5)
@@ -704,14 +697,6 b' def _runcommand(ui, options, cmd, cmdfun'
704 " - Ignored\n") % format)
697 " - Ignored\n") % format)
705 format = 'text'
698 format = 'text'
706
699
707 output = ui.config('profiling', 'output')
708
709 if output:
710 path = ui.expandpath(output)
711 ostream = open(path, 'wb')
712 else:
713 ostream = sys.stderr
714
715 try:
700 try:
716 from mercurial import lsprof
701 from mercurial import lsprof
717 except ImportError:
702 except ImportError:
@@ -721,21 +706,70 b' def _runcommand(ui, options, cmd, cmdfun'
721 p = lsprof.Profiler()
706 p = lsprof.Profiler()
722 p.enable(subcalls=True)
707 p.enable(subcalls=True)
723 try:
708 try:
724 return checkargs()
709 return func()
725 finally:
710 finally:
726 p.disable()
711 p.disable()
727
712
728 if format == 'kcachegrind':
713 if format == 'kcachegrind':
729 import lsprofcalltree
714 import lsprofcalltree
730 calltree = lsprofcalltree.KCacheGrind(p)
715 calltree = lsprofcalltree.KCacheGrind(p)
731 calltree.output(ostream)
716 calltree.output(fp)
732 else:
717 else:
733 # format == 'text'
718 # format == 'text'
734 stats = lsprof.Stats(p.getstats())
719 stats = lsprof.Stats(p.getstats())
735 stats.sort(field)
720 stats.sort(field)
736 stats.pprint(limit=30, file=ostream, climit=climit)
721 stats.pprint(limit=30, file=fp, climit=climit)
722
723 def statprofile(ui, func, fp):
724 try:
725 import statprof
726 except ImportError:
727 raise util.Abort(_(
728 'statprof not available - install using "easy_install statprof"'))
729
730 freq = ui.configint('profiling', 'freq', default=1000)
731 if freq > 0:
732 statprof.reset(freq)
733 else:
734 ui.warn(_("invalid sampling frequency '%s' - ignoring\n") % freq)
735
736 statprof.start()
737 try:
738 return func()
739 finally:
740 statprof.stop()
741 statprof.display(fp)
742
743 def _runcommand(ui, options, cmd, cmdfunc):
744 def checkargs():
745 try:
746 return cmdfunc()
747 except error.SignatureError:
748 raise error.CommandError(cmd, _("invalid arguments"))
749
750 if options['profile']:
751 profiler = os.getenv('HGPROF')
752 if profiler is None:
753 profiler = ui.config('profiling', 'type', default='ls')
754 if profiler not in ('ls', 'stat'):
755 ui.warn(_("unrecognized profiler '%s' - ignored\n") % profiler)
756 profiler = 'ls'
757
758 output = ui.config('profiling', 'output')
737
759
738 if output:
760 if output:
739 ostream.close()
761 path = ui.expandpath(output)
762 fp = open(path, 'wb')
763 else:
764 fp = sys.stderr
765
766 try:
767 if profiler == 'ls':
768 return lsprofile(ui, checkargs, fp)
769 else:
770 return statprofile(ui, checkargs, fp)
771 finally:
772 if output:
773 fp.close()
740 else:
774 else:
741 return checkargs()
775 return checkargs()
@@ -938,14 +938,31 b' information about working with phases.'
938 ``profiling``
938 ``profiling``
939 """""""""""""
939 """""""""""""
940
940
941 Specifies profiling format and file output. In this section
941 Specifies profiling type, format, and file output. Two profilers are
942 description, 'profiling data' stands for the raw data collected
942 supported: an instrumenting profiler (named ``ls``), and a sampling
943 during profiling, while 'profiling report' stands for a statistical
943 profiler (named ``stat``).
944 text report generated from the profiling data. The profiling is done
944
945 using lsprof.
945 In this section description, 'profiling data' stands for the raw data
946 collected during profiling, while 'profiling report' stands for a
947 statistical text report generated from the profiling data. The
948 profiling is done using lsprof.
949
950 ``type``
951 The type of profiler to use.
952 Default: ls.
953
954 ``ls``
955 Use Python's built-in instrumenting profiler. This profiler
956 works on all platforms, but each line number it reports is the
957 first line of a function. This restriction makes it difficult to
958 identify the expensive parts of a non-trivial function.
959 ``stat``
960 Use a third-party statistical profiler, statprof. This profiler
961 currently runs only on Unix systems, and is most useful for
962 profiling commands that run for longer than about 0.1 seconds.
946
963
947 ``format``
964 ``format``
948 Profiling format.
965 Profiling format. Specific to the ``ls`` instrumenting profiler.
949 Default: text.
966 Default: text.
950
967
951 ``text``
968 ``text``
@@ -957,6 +974,10 b' using lsprof.'
957 file, the generated file can directly be loaded into
974 file, the generated file can directly be loaded into
958 kcachegrind.
975 kcachegrind.
959
976
977 ``frequency``
978 Sampling frequency. Specific to the ``stat`` sampling profiler.
979 Default: 1000.
980
960 ``output``
981 ``output``
961 File path where profiling data or report should be saved. If the
982 File path where profiling data or report should be saved. If the
962 file exists, it is replaced. Default: None, data is printed on
983 file exists, it is replaced. Default: None, data is printed on
General Comments 0
You need to be logged in to leave comments. Login now