| 
									
										
										
										
											1992-04-21 15:36:23 +00:00
										 |  |  | # | 
					
						
							|  |  |  | # Class for profiling python code. | 
					
						
							|  |  |  | # Author: Sjoerd Mullender | 
					
						
							| 
									
										
										
										
											1992-09-02 20:43:20 +00:00
										 |  |  | # Hacked somewhat by: Guido van Rossum | 
					
						
							| 
									
										
										
										
											1992-04-21 15:36:23 +00:00
										 |  |  | # | 
					
						
							|  |  |  | # See the accompanying document profile.doc for more information. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import sys | 
					
						
							|  |  |  | import codehack | 
					
						
							| 
									
										
										
										
											1992-09-02 20:43:20 +00:00
										 |  |  | import os | 
					
						
							|  |  |  | import string | 
					
						
							|  |  |  | import fpformat | 
					
						
							|  |  |  | import marshal | 
					
						
							| 
									
										
										
										
											1992-04-21 15:36:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1993-05-24 14:16:22 +00:00
										 |  |  | class Profile: | 
					
						
							| 
									
										
										
										
											1992-04-21 15:36:23 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	def init(self): | 
					
						
							|  |  |  | 		self.timings = {} | 
					
						
							|  |  |  | 		self.debug = None | 
					
						
							|  |  |  | 		self.call_level = 0 | 
					
						
							|  |  |  | 		self.profile_func = None | 
					
						
							|  |  |  | 		self.profiling = 0 | 
					
						
							|  |  |  | 		return self | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def profile(self, funcname): | 
					
						
							|  |  |  | 		if not self.profile_func: | 
					
						
							|  |  |  | 			self.profile_func = {} | 
					
						
							|  |  |  | 		self.profile_func[funcname] = 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def trace_dispatch(self, frame, event, arg): | 
					
						
							|  |  |  | 		if event == 'call': | 
					
						
							|  |  |  | 			funcname = codehack.getcodename(frame.f_code) | 
					
						
							|  |  |  | 			if self.profile_func and not self.profiling: | 
					
						
							|  |  |  | 				if self.profile_func.has_key(funcname): | 
					
						
							|  |  |  | 					return | 
					
						
							|  |  |  | 				self.profiling = 1 | 
					
						
							| 
									
										
										
										
											1992-09-02 20:43:20 +00:00
										 |  |  | 			t = os.times() | 
					
						
							| 
									
										
										
										
											1992-04-21 15:36:23 +00:00
										 |  |  | 			t = t[0] + t[1] | 
					
						
							| 
									
										
										
										
											1993-08-25 14:09:01 +00:00
										 |  |  | 			if frame.f_locals.has_key('__key'): | 
					
						
							|  |  |  | 				key = frame.f_locals['__key'] | 
					
						
							|  |  |  | 			else: | 
					
						
							|  |  |  | 				lineno = codehack.getlineno(frame.f_code) | 
					
						
							|  |  |  | 				filename = frame.f_code.co_filename | 
					
						
							|  |  |  | 				key = filename + ':' + `lineno` + '(' + funcname + ')' | 
					
						
							|  |  |  | 				frame.f_locals['__key'] = key | 
					
						
							| 
									
										
										
										
											1992-04-21 15:36:23 +00:00
										 |  |  | 			self.call_level = depth(frame) | 
					
						
							|  |  |  | 			self.cur_frame = frame | 
					
						
							|  |  |  | 			pframe = frame.f_back | 
					
						
							|  |  |  | 			if self.debug: | 
					
						
							|  |  |  | 				s0 = 'call: ' + key + ' depth: ' + `self.call_level` + ' time: ' + `t` | 
					
						
							|  |  |  | 			if pframe: | 
					
						
							| 
									
										
										
										
											1993-08-25 14:09:01 +00:00
										 |  |  | 				if pframe.f_locals.has_key('__key'): | 
					
						
							|  |  |  | 					pkey = pframe.f_locals['__key'] | 
					
						
							|  |  |  | 				else: | 
					
						
							|  |  |  | 					pkey = pframe.f_code.co_filename + \ | 
					
						
							|  |  |  | 						  ':' + \ | 
					
						
							|  |  |  | 						  `codehack.getlineno(pframe.f_code)` \ | 
					
						
							|  |  |  | 						  + '(' + \ | 
					
						
							|  |  |  | 						  codehack.getcodename(pframe.f_code) \ | 
					
						
							|  |  |  | 						  + ')' | 
					
						
							|  |  |  | 					pframe.f_locals['__key'] = pkey | 
					
						
							| 
									
										
										
										
											1992-04-21 15:36:23 +00:00
										 |  |  | 				if self.debug: | 
					
						
							|  |  |  | 					s1 = 'parent: ' + pkey | 
					
						
							|  |  |  | 				if pframe.f_locals.has_key('__start_time'): | 
					
						
							|  |  |  | 					st = pframe.f_locals['__start_time'] | 
					
						
							| 
									
										
										
										
											1992-09-02 20:43:20 +00:00
										 |  |  | 					nc, tt, ct, callers, callees = \ | 
					
						
							|  |  |  | 						self.timings[pkey] | 
					
						
							| 
									
										
										
										
											1992-04-21 15:36:23 +00:00
										 |  |  | 					if self.debug: | 
					
						
							|  |  |  | 						s1 = s1+' before: st='+`st`+' nc='+`nc`+' tt='+`tt`+' ct='+`ct` | 
					
						
							|  |  |  | 					if callers.has_key(key): | 
					
						
							|  |  |  | 						callers[key] = callers[key] + 1 | 
					
						
							|  |  |  | 					else: | 
					
						
							|  |  |  | 						callers[key] = 1 | 
					
						
							|  |  |  | 					if self.debug: | 
					
						
							|  |  |  | 						s1 = s1+' after: st='+`st`+' nc='+`nc`+' tt='+`tt+(t-st)`+' ct='+`ct` | 
					
						
							|  |  |  | 					self.timings[pkey] = nc, tt + (t - st), ct, callers, callees | 
					
						
							|  |  |  | 			if self.timings.has_key(key): | 
					
						
							|  |  |  | 				nc, tt, ct, callers, callees = self.timings[key] | 
					
						
							|  |  |  | 			else: | 
					
						
							|  |  |  | 				nc, tt, ct, callers, callees = 0, 0, 0, {}, {} | 
					
						
							|  |  |  | 			if self.debug: | 
					
						
							|  |  |  | 				s0 = s0+' before: nc='+`nc`+' tt='+`tt`+' ct='+`ct` | 
					
						
							|  |  |  | 				s0 = s0+' after: nc='+`nc+1`+' tt='+`tt`+' ct='+`ct` | 
					
						
							|  |  |  | 			if pframe: | 
					
						
							|  |  |  | 				if callees.has_key(pkey): | 
					
						
							|  |  |  | 					callees[pkey] = callees[pkey] + 1 | 
					
						
							|  |  |  | 				else: | 
					
						
							|  |  |  | 					callees[pkey] = 1 | 
					
						
							|  |  |  | 			self.timings[key] = nc + 1, tt, ct, callers, callees | 
					
						
							|  |  |  | 			frame.f_locals['__start_time'] = t | 
					
						
							|  |  |  | 			if self.debug: | 
					
						
							|  |  |  | 				print s0 | 
					
						
							|  |  |  | 				print s1 | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		if event == 'return': | 
					
						
							|  |  |  | 			if self.profile_func: | 
					
						
							|  |  |  | 				if not self.profiling: | 
					
						
							|  |  |  | 					return | 
					
						
							| 
									
										
										
										
											1992-09-02 20:43:20 +00:00
										 |  |  | 				if self.profile_func.has_key( \ | 
					
						
							|  |  |  | 					codehack.getcodename(frame.f_code)): | 
					
						
							| 
									
										
										
										
											1992-04-21 15:36:23 +00:00
										 |  |  | 					self.profiling = 0 | 
					
						
							|  |  |  | 			self.call_level = depth(frame) | 
					
						
							|  |  |  | 			self.cur_frame = frame | 
					
						
							|  |  |  | 			pframe = frame.f_back | 
					
						
							|  |  |  | 			if self.debug: | 
					
						
							|  |  |  | 				s0 = 'return: ' | 
					
						
							|  |  |  | 			else: | 
					
						
							|  |  |  | 				s0 = None | 
					
						
							|  |  |  | 			self.handle_return(pframe, frame, s0) | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		if event == 'exception': | 
					
						
							|  |  |  | 			if self.profile_func and not self.profiling: | 
					
						
							|  |  |  | 				return | 
					
						
							|  |  |  | 			call_level = depth(frame) | 
					
						
							|  |  |  | 			if call_level < self.call_level: | 
					
						
							|  |  |  | 				if call_level <> self.call_level - 1: | 
					
						
							|  |  |  | 					print 'heh!',call_level,self.call_level | 
					
						
							|  |  |  | 				if self.debug: | 
					
						
							|  |  |  | 					s0 = 'exception: ' | 
					
						
							|  |  |  | 				else: | 
					
						
							|  |  |  | 					s0 = None | 
					
						
							|  |  |  | 				self.handle_return(self.cur_frame, frame, s0) | 
					
						
							|  |  |  | 			self.call_level = call_level | 
					
						
							|  |  |  | 			self.cur_frame = frame | 
					
						
							|  |  |  | 			return | 
					
						
							| 
									
										
										
										
											1992-09-02 20:43:20 +00:00
										 |  |  | 		print 'profile.Profile.dispatch: unknown debugging event:', | 
					
						
							|  |  |  | 		print `event` | 
					
						
							| 
									
										
										
										
											1992-04-21 15:36:23 +00:00
										 |  |  | 		return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def handle_return(self, pframe, frame, s0): | 
					
						
							| 
									
										
										
										
											1992-09-02 20:43:20 +00:00
										 |  |  | 		t = os.times() | 
					
						
							| 
									
										
										
										
											1992-04-21 15:36:23 +00:00
										 |  |  | 		t = t[0] + t[1] | 
					
						
							| 
									
										
										
										
											1993-08-25 14:09:01 +00:00
										 |  |  | 		if frame.f_locals.has_key('__key'): | 
					
						
							|  |  |  | 			key = frame.f_locals['__key'] | 
					
						
							|  |  |  | 		else: | 
					
						
							| 
									
										
										
										
											1992-04-21 15:36:23 +00:00
										 |  |  | 			funcname = codehack.getcodename(frame.f_code) | 
					
						
							|  |  |  | 			lineno = codehack.getlineno(frame.f_code) | 
					
						
							|  |  |  | 			filename = frame.f_code.co_filename | 
					
						
							| 
									
										
										
										
											1993-08-25 14:09:01 +00:00
										 |  |  | 			key = filename + ':' + `lineno` + '(' + funcname + ')' | 
					
						
							|  |  |  | 			frame.f_locals['__key'] = key | 
					
						
							|  |  |  | 		if self.debug: | 
					
						
							|  |  |  | 			s0 = s0 + key + ' depth: ' + `self.call_level` + ' time: ' + `t` | 
					
						
							|  |  |  | 		if pframe: | 
					
						
							|  |  |  | 			if pframe.f_locals.has_key('__key'): | 
					
						
							|  |  |  | 				pkey = pframe.f_locals['__key'] | 
					
						
							|  |  |  | 			else: | 
					
						
							|  |  |  | 				funcname = codehack.getcodename(frame.f_code) | 
					
						
							|  |  |  | 				lineno = codehack.getlineno(frame.f_code) | 
					
						
							|  |  |  | 				filename = frame.f_code.co_filename | 
					
						
							|  |  |  | 				pkey = filename + ':' + `lineno` + '(' + funcname + ')' | 
					
						
							|  |  |  | 				pframe.f_locals['__key'] = pkey | 
					
						
							| 
									
										
										
										
											1992-04-21 15:36:23 +00:00
										 |  |  | 			if self.debug: | 
					
						
							|  |  |  | 				s1 = 'parent: '+pkey | 
					
						
							|  |  |  | 			if pframe.f_locals.has_key('__start_time') and \ | 
					
						
							|  |  |  | 				  self.timings.has_key(pkey): | 
					
						
							|  |  |  | 				st = pframe.f_locals['__start_time'] | 
					
						
							| 
									
										
										
										
											1992-09-02 20:43:20 +00:00
										 |  |  | 				nc, tt, ct, callers, callees = \ | 
					
						
							|  |  |  | 					self.timings[pkey] | 
					
						
							| 
									
										
										
										
											1992-04-21 15:36:23 +00:00
										 |  |  | 				if self.debug: | 
					
						
							|  |  |  | 					s1 = s1+' before: st='+`st`+' nc='+`nc`+' tt='+`tt`+' ct='+`ct` | 
					
						
							|  |  |  | 					s1 = s1+' after: st='+`t`+' nc='+`nc`+' tt='+`tt`+' ct='+`ct+(t-st)` | 
					
						
							| 
									
										
										
										
											1992-09-02 20:43:20 +00:00
										 |  |  | 				self.timings[pkey] = \ | 
					
						
							|  |  |  | 					nc, tt, ct + (t - st), callers, callees | 
					
						
							| 
									
										
										
										
											1992-04-21 15:36:23 +00:00
										 |  |  | 				pframe.f_locals['__start_time'] = t | 
					
						
							|  |  |  | 		if self.timings.has_key(key): | 
					
						
							|  |  |  | 			nc, tt, ct, callers, callees = self.timings[key] | 
					
						
							|  |  |  | 		else: | 
					
						
							|  |  |  | 			nc, tt, ct, callers, callees = 0, 0, 0, {}, {} | 
					
						
							|  |  |  | 		if frame.f_locals.has_key('__start_time'): | 
					
						
							|  |  |  | 			st = frame.f_locals['__start_time'] | 
					
						
							|  |  |  | 		else: | 
					
						
							|  |  |  | 			st = t | 
					
						
							|  |  |  | 		if self.debug: | 
					
						
							|  |  |  | 			s0 = s0+' before: st='+`st`+' nc='+`nc`+' tt='+`tt`+' ct='+`ct` | 
					
						
							|  |  |  | 			s0 = s0+' after: nc='+`nc`+' tt='+`tt+(t-st)`+' ct='+`ct+(t-st)` | 
					
						
							|  |  |  | 			print s0 | 
					
						
							|  |  |  | 			print s1 | 
					
						
							| 
									
										
										
										
											1992-09-02 20:43:20 +00:00
										 |  |  | 		self.timings[key] = \ | 
					
						
							|  |  |  | 			nc, tt + (t - st), ct + (t - st), callers, callees | 
					
						
							| 
									
										
										
										
											1992-04-21 15:36:23 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	def print_stats(self): | 
					
						
							| 
									
										
										
										
											1992-09-02 20:43:20 +00:00
										 |  |  | 		# Print in reverse order by ct | 
					
						
							|  |  |  | 		print_title() | 
					
						
							|  |  |  | 		list = [] | 
					
						
							| 
									
										
										
										
											1992-04-21 15:36:23 +00:00
										 |  |  | 		for key in self.timings.keys(): | 
					
						
							|  |  |  | 			nc, tt, ct, callers, callees = self.timings[key] | 
					
						
							|  |  |  | 			if nc == 0: | 
					
						
							|  |  |  | 				continue | 
					
						
							| 
									
										
										
										
											1992-09-02 20:43:20 +00:00
										 |  |  | 			list.append(ct, tt, nc, key) | 
					
						
							|  |  |  | 		list.sort() | 
					
						
							|  |  |  | 		list.reverse() | 
					
						
							|  |  |  | 		for ct, tt, nc, key in list: | 
					
						
							|  |  |  | 			print_line(nc, tt, ct, os.path.basename(key)) | 
					
						
							| 
									
										
										
										
											1992-04-21 15:36:23 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	def dump_stats(self, file): | 
					
						
							|  |  |  | 		f = open(file, 'w') | 
					
						
							|  |  |  | 		marshal.dump(self.timings, f) | 
					
						
							|  |  |  | 		f.close() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-09-02 20:43:20 +00:00
										 |  |  | 	# The following two methods can be called by clients to use | 
					
						
							|  |  |  | 	# a profiler to profile a statement, given as a string. | 
					
						
							| 
									
										
										
										
											1992-04-21 15:36:23 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	def run(self, cmd): | 
					
						
							|  |  |  | 		import __main__ | 
					
						
							|  |  |  | 		dict = __main__.__dict__ | 
					
						
							|  |  |  | 		self.runctx(cmd, dict, dict) | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	def runctx(self, cmd, globals, locals): | 
					
						
							|  |  |  | 		sys.setprofile(self.trace_dispatch) | 
					
						
							|  |  |  | 		try: | 
					
						
							| 
									
										
										
										
											1992-09-02 20:43:20 +00:00
										 |  |  | 			exec(cmd + '\n', globals, locals) | 
					
						
							| 
									
										
										
										
											1992-04-21 15:36:23 +00:00
										 |  |  | 		finally: | 
					
						
							|  |  |  | 			sys.setprofile(None) | 
					
						
							| 
									
										
										
										
											1992-09-02 20:43:20 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	# This method is more useful to profile a single function call. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def runcall(self, func, *args): | 
					
						
							|  |  |  | 		sys.setprofile(self.trace_dispatch) | 
					
						
							|  |  |  | 		try: | 
					
						
							|  |  |  | 			apply(func, args) | 
					
						
							|  |  |  | 		finally: | 
					
						
							|  |  |  | 			sys.setprofile(None) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-04-21 15:36:23 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def depth(frame): | 
					
						
							|  |  |  | 	d = 0 | 
					
						
							|  |  |  | 	while frame: | 
					
						
							|  |  |  | 		d = d + 1 | 
					
						
							|  |  |  | 		frame = frame.f_back | 
					
						
							|  |  |  | 	return d | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1993-05-24 14:16:22 +00:00
										 |  |  | class Stats: | 
					
						
							| 
									
										
										
										
											1992-04-21 15:36:23 +00:00
										 |  |  | 	def init(self, file): | 
					
						
							|  |  |  | 		f = open(file, 'r') | 
					
						
							|  |  |  | 		self.stats = marshal.load(f) | 
					
						
							|  |  |  | 		f.close() | 
					
						
							|  |  |  | 		self.stats_list = None | 
					
						
							|  |  |  | 		return self | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def print_stats(self): | 
					
						
							| 
									
										
										
										
											1992-09-02 20:43:20 +00:00
										 |  |  | 		print_title() | 
					
						
							| 
									
										
										
										
											1992-04-21 15:36:23 +00:00
										 |  |  | 		if self.stats_list: | 
					
						
							|  |  |  | 			for i in range(len(self.stats_list)): | 
					
						
							| 
									
										
										
										
											1992-09-02 20:43:20 +00:00
										 |  |  | 				nc, tt, ct, callers, callees, key = \ | 
					
						
							|  |  |  | 					self.stats_list[i] | 
					
						
							|  |  |  | 				print_line(nc, tt, ct, key) | 
					
						
							| 
									
										
										
										
											1992-04-21 15:36:23 +00:00
										 |  |  | 		else: | 
					
						
							|  |  |  | 			for key in self.stats.keys(): | 
					
						
							|  |  |  | 				nc, tt, ct, callers, callees = self.stats[key] | 
					
						
							| 
									
										
										
										
											1992-09-02 20:43:20 +00:00
										 |  |  | 				print_line(nc, tt, ct, key) | 
					
						
							| 
									
										
										
										
											1992-04-21 15:36:23 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	def print_callers(self): | 
					
						
							|  |  |  | 		if self.stats_list: | 
					
						
							|  |  |  | 			for i in range(len(self.stats_list)): | 
					
						
							| 
									
										
										
										
											1992-09-02 20:43:20 +00:00
										 |  |  | 				nc, tt, ct, callers, callees, key = \ | 
					
						
							|  |  |  | 					self.stats_list[i] | 
					
						
							| 
									
										
										
										
											1992-04-21 15:36:23 +00:00
										 |  |  | 				print key, | 
					
						
							|  |  |  | 				for func in callers.keys(): | 
					
						
							|  |  |  | 					print func+'('+`callers[func]`+')', | 
					
						
							|  |  |  | 				print | 
					
						
							|  |  |  | 		else: | 
					
						
							|  |  |  | 			for key in self.stats.keys(): | 
					
						
							|  |  |  | 				nc, tt, ct, callers, callees = self.stats[key] | 
					
						
							|  |  |  | 				print key, | 
					
						
							|  |  |  | 				for func in callers.keys(): | 
					
						
							|  |  |  | 					print func+'('+`callers[func]`+')', | 
					
						
							|  |  |  | 				print | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def print_callees(self): | 
					
						
							|  |  |  | 		if self.stats_list: | 
					
						
							|  |  |  | 			for i in range(len(self.stats_list)): | 
					
						
							| 
									
										
										
										
											1992-09-02 20:43:20 +00:00
										 |  |  | 				nc, tt, ct, callers, callees, key = \ | 
					
						
							|  |  |  | 					self.stats_list[i] | 
					
						
							| 
									
										
										
										
											1992-04-21 15:36:23 +00:00
										 |  |  | 				print key, | 
					
						
							|  |  |  | 				for func in callees.keys(): | 
					
						
							|  |  |  | 					print func+'('+`callees[func]`+')', | 
					
						
							|  |  |  | 				print | 
					
						
							|  |  |  | 		else: | 
					
						
							|  |  |  | 			for key in self.stats.keys(): | 
					
						
							|  |  |  | 				nc, tt, ct, callers, callees = self.stats[key] | 
					
						
							|  |  |  | 				print key, | 
					
						
							|  |  |  | 				for func in callees.keys(): | 
					
						
							|  |  |  | 					print func+'('+`callees[func]`+')', | 
					
						
							|  |  |  | 				print | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def sort_stats(self, field): | 
					
						
							|  |  |  | 		stats_list = [] | 
					
						
							|  |  |  | 		for key in self.stats.keys(): | 
					
						
							|  |  |  | 			t = self.stats[key] | 
					
						
							|  |  |  | 			nt = () | 
					
						
							|  |  |  | 			for i in range(len(t)): | 
					
						
							|  |  |  | 				if i == field: | 
					
						
							|  |  |  | 					nt = (t[i],) + nt[:] | 
					
						
							|  |  |  | 				else: | 
					
						
							|  |  |  | 					nt = nt[:] + (t[i],) | 
					
						
							|  |  |  | 			if field == -1: | 
					
						
							|  |  |  | 				nt = (key,) + nt | 
					
						
							|  |  |  | 			else: | 
					
						
							|  |  |  | 				nt = nt + (key,) | 
					
						
							|  |  |  | 			stats_list.append(nt) | 
					
						
							|  |  |  | 		stats_list.sort() | 
					
						
							|  |  |  | 		self.stats_list = [] | 
					
						
							|  |  |  | 		for i in range(len(stats_list)): | 
					
						
							|  |  |  | 			t = stats_list[i] | 
					
						
							|  |  |  | 			if field == -1: | 
					
						
							|  |  |  | 				nt = t[1:] + t[0:1] | 
					
						
							|  |  |  | 			else: | 
					
						
							|  |  |  | 				nt = t[1:] | 
					
						
							|  |  |  | 				nt = nt[:field] + t[0:1] + nt[field:] | 
					
						
							|  |  |  | 			self.stats_list.append(nt) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-09-02 20:43:20 +00:00
										 |  |  | 	def reverse_order(self): | 
					
						
							|  |  |  | 		self.stats_list.reverse() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-04-21 15:36:23 +00:00
										 |  |  | 	def strip_dirs(self): | 
					
						
							|  |  |  | 		newstats = {} | 
					
						
							|  |  |  | 		for key in self.stats.keys(): | 
					
						
							|  |  |  | 			nc, tt, ct, callers, callees = self.stats[key] | 
					
						
							|  |  |  | 			newkey = os.path.basename(key) | 
					
						
							|  |  |  | 			newcallers = {} | 
					
						
							|  |  |  | 			for c in callers.keys(): | 
					
						
							|  |  |  | 				newcallers[os.path.basename(c)] = callers[c] | 
					
						
							|  |  |  | 			newcallees = {} | 
					
						
							|  |  |  | 			for c in callees.keys(): | 
					
						
							|  |  |  | 				newcallees[os.path.basename(c)] = callees[c] | 
					
						
							|  |  |  | 			newstats[newkey] = nc, tt, ct, newcallers, newcallees | 
					
						
							|  |  |  | 		self.stats = newstats | 
					
						
							|  |  |  | 		self.stats_list = None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-09-02 20:43:20 +00:00
										 |  |  | def print_title(): | 
					
						
							|  |  |  | 	print string.rjust('ncalls', 8), | 
					
						
							|  |  |  | 	print string.rjust('tottime', 8), | 
					
						
							|  |  |  | 	print string.rjust('percall', 8), | 
					
						
							|  |  |  | 	print string.rjust('cumtime', 8), | 
					
						
							|  |  |  | 	print string.rjust('percall', 8), | 
					
						
							|  |  |  | 	print 'filename:lineno(function)' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def print_line(nc, tt, ct, key): | 
					
						
							|  |  |  | 	print string.rjust(`nc`, 8), | 
					
						
							|  |  |  | 	print f8(tt), | 
					
						
							|  |  |  | 	if nc == 0: | 
					
						
							|  |  |  | 		print ' '*8, | 
					
						
							|  |  |  | 	else: | 
					
						
							|  |  |  | 		print f8(tt/nc), | 
					
						
							|  |  |  | 	print f8(ct), | 
					
						
							|  |  |  | 	if nc == 0: | 
					
						
							|  |  |  | 		print ' '*8, | 
					
						
							|  |  |  | 	else: | 
					
						
							|  |  |  | 		print f8(ct/nc), | 
					
						
							|  |  |  | 	print key | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def f8(x): | 
					
						
							|  |  |  | 	return string.rjust(fpformat.fix(x, 3), 8) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # simplified user interface | 
					
						
							|  |  |  | def run(statement, *args): | 
					
						
							|  |  |  | 	prof = Profile().init() | 
					
						
							|  |  |  | 	try: | 
					
						
							|  |  |  | 		prof.run(statement) | 
					
						
							|  |  |  | 	except SystemExit: | 
					
						
							|  |  |  | 		pass | 
					
						
							|  |  |  | 	if len(args) == 0: | 
					
						
							|  |  |  | 		prof.print_stats() | 
					
						
							|  |  |  | 	else: | 
					
						
							|  |  |  | 		prof.dump_stats(args[0]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # test command with debugging | 
					
						
							| 
									
										
										
										
											1992-04-21 15:36:23 +00:00
										 |  |  | def debug(): | 
					
						
							|  |  |  | 	prof = Profile().init() | 
					
						
							|  |  |  | 	prof.debug = 1 | 
					
						
							|  |  |  | 	try: | 
					
						
							|  |  |  | 		prof.run('import x; x.main()') | 
					
						
							|  |  |  | 	except SystemExit: | 
					
						
							|  |  |  | 		pass | 
					
						
							|  |  |  | 	prof.print_stats() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-09-02 20:43:20 +00:00
										 |  |  | # test command | 
					
						
							| 
									
										
										
										
											1992-04-21 15:36:23 +00:00
										 |  |  | def test(): | 
					
						
							|  |  |  | 	run('import x; x.main()') | 
					
						
							| 
									
										
										
										
											1993-10-22 13:56:35 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | # print help | 
					
						
							|  |  |  | def help(): | 
					
						
							|  |  |  | 	for dirname in sys.path: | 
					
						
							|  |  |  | 		fullname = os.path.join(dirname, 'profile.doc') | 
					
						
							|  |  |  | 		if os.path.exists(fullname): | 
					
						
							|  |  |  | 			sts = os.system('${PAGER-more} '+fullname) | 
					
						
							|  |  |  | 			if sts: print '*** Pager exit status:', sts | 
					
						
							|  |  |  | 			break | 
					
						
							|  |  |  | 	else: | 
					
						
							|  |  |  | 		print 'Sorry, can\'t find the help file "profile.doc"', | 
					
						
							|  |  |  | 		print 'along the Python search path' |