profile.py 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. # extensions for lsprof/cProfile
  2. #
  3. # usage:
  4. #
  5. # from BTL.profile import Profiler, Stats
  6. #
  7. # prof = Profiler()
  8. # prof.enable()
  9. #
  10. # your_code()
  11. #
  12. # prof.disable()
  13. # stats = Stats(prof.getstats())
  14. # stats.sort("inlinetime")
  15. # stats.pprint()
  16. #
  17. # by Greg Hazel
  18. from __future__ import division
  19. import sys
  20. from BTL.ebencode import ebencode
  21. from lsprof import Profiler, _fn2mod
  22. from lsprof import Stats as lsprof_Stats
  23. def label(code):
  24. if isinstance(code, str):
  25. return code
  26. try:
  27. mname = _fn2mod[code.co_filename]
  28. except KeyError:
  29. for k, v in sys.modules.items():
  30. if v is None:
  31. continue
  32. if not hasattr(v, '__file__'):
  33. continue
  34. if not isinstance(v.__file__, str):
  35. continue
  36. if v.__file__.startswith(code.co_filename):
  37. mname = _fn2mod[code.co_filename] = k
  38. break
  39. else:
  40. mname = _fn2mod[code.co_filename] = '<%s>'%code.co_filename
  41. return '%s (%s:%d)' % (code.co_name, mname, code.co_firstlineno)
  42. class Stats(lsprof_Stats):
  43. def dump(self, file, top=None):
  44. d = self.data
  45. if top is not None:
  46. d = d[:top]
  47. root = []
  48. for e in d:
  49. n = {}
  50. root.append(n)
  51. n['l'] = (e.inlinetime, e.callcount, e.totaltime, label(e.code))
  52. n['c'] = []
  53. for se in e.calls or []:
  54. n['c'].append((se.inlinetime, se.callcount,
  55. se.totaltime, label(se.code)))
  56. file.write(ebencode(root))
  57. def list_stats(self, top=None):
  58. l = []
  59. d = self.data
  60. if top is not None:
  61. d = d[:top]
  62. l.append(("CallCount",
  63. "Inline(sec)", "Per call(sec)",
  64. "Total(sec)", "Per call(sec)",
  65. "function (module:lineno)"))
  66. def make_set(d, child=False):
  67. if child:
  68. fmt = "+%s"
  69. else:
  70. fmt = "%s"
  71. return (fmt % d.callcount,
  72. '%.3f' % d.inlinetime,
  73. '%.3f' % (d.inlinetime / e.callcount),
  74. '%.3f' % d.totaltime,
  75. '%.3f' % (d.totaltime / e.callcount),
  76. fmt % label(d.code))
  77. for e in d:
  78. l.append(make_set(e))
  79. if e.calls:
  80. for se in e.calls:
  81. l.append(make_set(se, child=True))
  82. return l