def _tree_handler(self, environ, start_response): params = _parse_params(environ) node_thres = float(params.get('node_thres', 0.5)) edge_thres = float(params.get('edge_thres', 0.1)) results = self._get_results_by_request(params) if not results: start_response('200 OK', [('Content-Type', 'text/plain')]) return [b'No matching log.'] # pstats.Stats() hits recursion limit when many profiles are passed. parser = gprof2dot.PstatsParser(results[0]) for result in results[1:]: parser.stats.add(result) parsed_profile = parser.parse() parsed_profile.prune(node_thres / 100.0, edge_thres / 100.0) output = io.StringIO() if six.PY3 else io.BytesIO() writer = gprof2dot.DotWriter(output) writer.graph(parsed_profile, gprof2dot.TEMPERATURE_COLORMAP) dot_data = output.getvalue() if six.PY3: dot_data = dot_data.encode('utf-8') try: proc = subprocess.Popen( ['dot', '-Tpng'], stdin=subprocess.PIPE, stdout=subprocess.PIPE) png_data, _ = proc.communicate(dot_data) except Exception: start_response('200 OK', [('Content-Type', 'text/plain')]) return [b'ERROR: Failed to execute "dot". Please install graphviz.'] else: start_response('200 OK', [('Content-Type', 'image/png')]) return [png_data]
def save_data(self): try: import gprof2dot import pyprof2calltree except ImportError: msg = ('Unable to start profiling.\n Please either ' 'disable performance profiling in settings.yaml or ' 'install all modules listed in test-requirements.txt.') raise error.ProfilingError(msg) self.profiler.disable() elapsed = time.time() - self.start pref_filename = os.path.join( self.paths['last_performance_test'], '{method:s}.{handler_name:s}.{elapsed_time:.0f}ms.{t_time}.'. format(method=self.method, handler_name=self.handler_name or 'root', elapsed_time=elapsed * 1000.0, t_time=time.time())) tree_file = pref_filename + 'prof' stats_file = pref_filename + 'txt' callgraph_file = pref_filename + 'dot' # write pstats with file(stats_file, 'w') as file_o: stats = Stats(self.profiler, stream=file_o) stats.sort_stats('time', 'cumulative').print_stats() # write callgraph in dot format parser = gprof2dot.PstatsParser(self.profiler) def get_function_name((filename, line, name)): module = os.path.splitext(filename)[0] module_pieces = module.split(os.path.sep) return "{module:s}:{line:d}:{name:s}".format(module="/".join( module_pieces[-4:]), line=line, name=name) parser.get_function_name = get_function_name gprof = parser.parse() with open(callgraph_file, 'w') as file_o: dot = gprof2dot.DotWriter(file_o) theme = gprof2dot.TEMPERATURE_COLORMAP dot.graph(gprof, theme) # write calltree call_tree = pyprof2calltree.CalltreeConverter(stats) with file(tree_file, 'wb') as file_o: call_tree.output(file_o)
def __rungprof2dot(self): """Runs gprof2dot which produces a full dot spec""" nodeLimit = Settings().getProfilerSettings().nodeLimit edgeLimit = Settings().getProfilerSettings().edgeLimit with io.StringIO() as buf: gprofParser = gprof2dot.PstatsParser(self.__dataFile) profileData = gprofParser.parse() profileData.prune(nodeLimit / 100.0, edgeLimit / 100.0, False) dot = gprof2dot.DotWriter(buf) dot.strip = False dot.wrap = False dot.graph(profileData, gprof2dot.TEMPERATURE_COLORMAP) output = buf.getvalue() return self.__postprocessFullDotSpec(output)
def _prepare_profile(self): """Prepares profiling information.""" if not self._profile_enabled or not hasattr(self, '_prof'): return None if not gprof2dot: logging.warn('failed to import ``gprof2dot``, will not profile') return None self._prof.create_stats() parser = gprof2dot.PstatsParser(self._prof) def get_function_name((filename, line, name)): module = os.path.splitext(filename)[0] module_pieces = module.split(os.path.sep) return "%s:%d:%s" % ("/".join(module_pieces[-4:]), line, name) parser.get_function_name = get_function_name output = StringIO() gprof = parser.parse() gprof.prune(0.005, 0.001) # TODO: ^--- Parameterize node and edge thresholds. dot = gprof2dot.DotWriter(output) theme = gprof2dot.TEMPERATURE_COLORMAP theme.bgcolor = (0.0, 0.0, 0.0) # ^--- Use black text, for less eye-bleeding. dot.graph(gprof, theme) def get_info(self): s = "Profile Graph:" s += " %.3fs CPU" % self.total_tt s += ": %d function calls" % self.total_calls if self.total_calls != self.prim_calls: s += " (%d primitive calls)" % self.prim_calls return s profile = { "producer": "gprof2dot", "producerVersion": str(gprof2dot.__version__), "info": get_info(parser.stats), "dot": output.getvalue(), } return profile
def _write_dot_graph(self, name, path, prune=''): parser = gprof2dot.PstatsParser(path) profile = parser.parse() funcId = self._find_func_id_for_test_case(profile, name) if funcId: profile.prune_root(funcId) if prune == self.PRUNED_CUMULATIVE: profile.prune(0.005, 0.001, None, True) elif prune == self.PRUNED_INTERNAL: profile.prune(0.005, 0.001, None, True) else: profile.prune(0, 0, None, False) with open(self._get_test_dot_filename(name, prune), 'wt') as f: dot = gprof2dot.DotWriter(f) dot.graph(profile, self.TEMPERATURE_COLORMAP)
def save_data(self): elapsed = time.time() - self.start pref_filename = os.path.join( settings.LOAD_TESTS_PATHS['last_performance_test'], '{method:s}.{handler_name:s}.{elapsed_time:.0f}ms.{t_time}.'. format( method=self.method, handler_name=self.handler_name or 'root', elapsed_time=elapsed * 1000.0, t_time=time.time())) tree_file = pref_filename + 'prof' stats_file = pref_filename + 'txt' callgraph_file = pref_filename + 'dot' # write pstats with file(stats_file, 'w') as file_o: stats = Stats(self.profiler, stream=file_o) stats.sort_stats('time', 'cumulative').print_stats() # write callgraph in dot format parser = gprof2dot.PstatsParser(self.profiler) def get_function_name((filename, line, name)): module = os.path.splitext(filename)[0] module_pieces = module.split(os.path.sep) return "{module:s}:{line:d}:{name:s}".format( module="/".join(module_pieces[-4:]), line=line, name=name) parser.get_function_name = get_function_name gprof = parser.parse() with open(callgraph_file, 'w') as file_o: dot = gprof2dot.DotWriter(file_o) theme = gprof2dot.TEMPERATURE_COLORMAP dot.graph(gprof, theme) # write calltree call_tree = pyprof2calltree.CalltreeConverter(stats) with file(tree_file, 'wb') as file_o: call_tree.output(file_o)
def wrapper(*args, **kwargs): # Build the path to the folder where we want to keep the results # Make sure this directory exists if not os.path.isdir(output_directory): os.makedirs(output_directory) # Run and profile the function, dumping the resulting stats into a # file in the results directory. pstats_file = os.path.join( output_directory, "%s_pstats_results.pstats" % (f.__name__)) profiler = cProfile.Profile() profiler.runcall(f, *args, **kwargs) profiler.dump_stats(pstats_file) # Dump the profile stats in a human readable for to a file on # disk stats_file = os.path.join( output_directory, "%s_profiler_results.stats" % (f.__name__)) # Temporarily redirect stdout to somewhere else fd = open(stats_file, "w") _stdout = sys.stdout sys.stdout = fd # Dump the stats to this file profiler.print_stats() # Point stdout back to what it should be sys.stdout = _stdout fd.close() # Now we want to dump the stats to a pretty graph. if graph: class FakeOptions(object): """A fake options object to trick the gprof2dot main method.""" pass # Setup an instance of gprof2dot, forcing some options that # would usually come through the command line. gprof = gprof2dot.Main() gprof.options = FakeOptions() gprof.options.node_thres = 0.5 gprof.options.edge_thres = 0.1 gprof.options.wrap = False gprof.options.strip = False gprof.options.theme = "color" gprof.theme = gprof2dot.Main.themes[gprof.options.theme] # Now build the graph parser = gprof2dot.PstatsParser(pstats_file) gprof.profile = parser.parse() dot_file = os.path.join(output_directory, "%s_dot_results.dot" % (f.__name__)) gprof.output = open(dot_file, 'wt') gprof.write_graph() gprof.output.close() dot_graph = pydot.graph_from_dot_file(dot_file) png_file = os.path.join(output_directory, "%s_profiler_graph.png" % (f.__name__)) dot_graph.write(png_file, format="png", prog="dot")
import pstats from glob import glob import gprof2dot import subprocess import shlex direct_ory = 'Results/dhfr-explicit/01-25-2016' profiles = dict() for dirname in glob('{}/*'.format(direct_ory), recursive=True): prof_file = '{}/benchmark.prof'.format(dirname) outputfile = '{}/bench.dot'.format(dirname) image = '{}/bench.png'.format(dirname) txt = '{}/bench_pstats.txt'.format(dirname) ps = pstats.Stats(prof_file, stream=open(txt, 'w')) ps.strip_dirs() ps.sort_stats('time') ps.print_stats() profile = gprof2dot.PstatsParser(prof_file).parse() profile.prune(0.5 / 100.0, 0.1 / 100.0) dot = gprof2dot.DotWriter(open(outputfile, 'wt', encoding='UTF-8')) dot.strip = False dot.wrap = False dot.graph(profile, gprof2dot.themes["color"])