Package coro :: Module profiler
[hide private]
[frames] | no frames]

Source Code for Module coro.profiler

  1  # Copyright (c) 2002-2011 IronPort Systems and Cisco Systems 
  2  #  
  3  # Permission is hereby granted, free of charge, to any person obtaining a copy 
  4  # of this software and associated documentation files (the "Software"), to deal 
  5  # in the Software without restriction, including without limitation the rights 
  6  # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
  7  # copies of the Software, and to permit persons to whom the Software is 
  8  # furnished to do so, subject to the following conditions: 
  9  #  
 10  # The above copyright notice and this permission notice shall be included in 
 11  # all copies or substantial portions of the Software. 
 12  #  
 13  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
 14  # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
 15  # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
 16  # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
 17  # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
 18  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
 19  # SOFTWARE. 
 20   
 21  # $Header: //prod/main/ap/shrapnel/coro/profiler.py#9 $ 
 22   
 23  """Coro code profiler. 
 24   
 25  Introduction 
 26  ============ 
 27  This profiler is coro-aware.  It produces output to a binary file on disk. You 
 28  then use the `coro.print_profile` module to convert it to an HTML file. 
 29   
 30  Using The Profiler 
 31  ================== 
 32  There are two ways to run the profiler.  One is to use the `go` function where 
 33  you give it a python function to run.  Profiling will start and call the 
 34  function, and then the profiler will automatically stop when the function 
 35  exits. 
 36   
 37  The other method is to call `start` to start the profiler and `stop` when you 
 38  want to stop profiling.  This can be conveniently done from the backdoor. 
 39   
 40  Rendering Output 
 41  ================ 
 42  Once you have profiler output, you must use the ``print_profile`` module 
 43  to convert it to HTML.  The typical method for doing this is:: 
 44   
 45      python -m coro.print_profile /tmp/coro_profile.bin > my_profile.html 
 46   
 47  Then view the profile output in your web browser. 
 48   
 49  Profiler Types 
 50  ============== 
 51  The profiler supports different ways of gathering statistics.  This is done by 
 52  specifying the "bench" object to use (see `go` and `start`).  They default to 
 53  the "rusage" method of gathering statistics about every function call (see the 
 54  getrusage man page for more detail).  If you want a higher performance profile, 
 55  you can use the `coro.bench` object instead which simply records TSC values for 
 56  every function call.  If you want to define your own method of gathering 
 57  statistics, subclass `coro.bench` and implement your own techniques. 
 58   
 59  """ 
 60   
 61  import coro 
 62  import cPickle 
 63  import time 
 64   
 65  MAGIC = 'SHRAP_PROF1' 
 66   
67 -def _dump(p, filename):
68 f = open(filename, 'w') 69 f.write(MAGIC) 70 data = (p.bench_class.__name__, p.bench_class().get_headings(), time.time()) 71 cPickle.dump(data, f, -1) 72 73 # Dump profile data. 74 data = {} 75 for func, bench in p.charges.iteritems(): 76 data[func.as_str()] = bench.get_data() 77 cPickle.dump(data, f, -1) 78 79 # Dump call data. 80 data = {} 81 for caller, cc in p.call_counts.iteritems(): 82 count_data = cc.get() 83 result = [] 84 for callee, count in count_data: 85 element = (callee.as_str(), count) 86 result.append(element) 87 data[caller.as_str()] = result 88 cPickle.dump(data, f, -1) 89 f.close()
90
91 -def go (fun, *args, **kwargs):
92 """Start the profiler on a function. 93 94 This will start the profiler, and then call the provided function. 95 The profiler will shut down once the function returns. 96 97 Additional arguments provided are passed to the function. 98 99 This will display the results to stdout after the function is finished. 100 101 :Parameters: 102 - `fun`: The function to call. 103 104 :Keywords: 105 - `profile_filename`: The name of the file to save the profile data. 106 Defaults to '/tmp/coro_profile.bin'. 107 - `profile_bench`: The bench object type to use. Defaults to 108 `coro.rusage_bench`. 109 """ 110 if kwargs.has_key('profile_filename'): 111 profile_filename = kwargs['profile_filename'] 112 del kwargs['profile_filename'] 113 else: 114 profile_filename = '/tmp/coro_profile.bin' 115 116 if kwargs.has_key('profile_bench'): 117 profile_bench = kwargs['profile_bench'] 118 del kwargs['profile_bench'] 119 else: 120 profile_bench = coro.rusage_bench 121 122 p = coro.new_profiler (profile_bench) 123 p.start() 124 try: 125 return fun (*args, **kwargs) 126 finally: 127 total_ticks = p.stop() 128 user_ticks = _dump (p, profile_filename)
129
130 -def start(profile_bench=coro.rusage_bench):
131 """Start the profiler. 132 133 :Parameters: 134 - `profile_bench`: The profiler type to use. 135 """ 136 p = coro.new_profiler(profile_bench) 137 p.start()
138
139 -def stop(filename='/tmp/coro_profile.bin'):
140 """Stop the profiler. 141 142 :Parameters: 143 - `filename`: The filename to use for the profile output. 144 """ 145 p = coro.get_the_profiler() 146 p.stop() 147 _dump(p, filename)
148
149 -def tak1 (x,y,z):
150 if y >= x: 151 return z 152 else: 153 return tak1 ( 154 tak1 (x-1, y, z), 155 tak2 (y-1, z, x), 156 tak2 (z-1, x, y) 157 )
158
159 -def tak2 (x,y,z):
160 if y >= x: 161 return z 162 else: 163 return tak2 ( 164 tak2 (x-1, y, z), 165 tak1 (y-1, z, x), 166 tak1 (z-1, x, y) 167 )
168 169 if __name__ == '__main__': 170 go (tak2, 18, 12, 6) 171 print 'now run print_profile.py ...' 172