mirror of
				https://github.com/lubuntu-team/ci-tooling.git
				synced 2025-10-30 21:54:02 +00:00 
			
		
		
		
	Initial commit of the timer_metrics module.
This commit is contained in:
		
							parent
							
								
									86f658cb55
								
							
						
					
					
						commit
						42869ace27
					
				
							
								
								
									
										0
									
								
								ci/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								ci/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										138
									
								
								ci/timer_metrics.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										138
									
								
								ci/timer_metrics.py
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,138 @@ | ||||
| #!/usr/bin/env python3 | ||||
| 
 | ||||
| # Copyright (C) 2020 Simon Quigley <tsimonq2@lubuntu.me> | ||||
| # | ||||
| # This program is free software: you can redistribute it and/or modify | ||||
| # it under the terms of the GNU General Public License as published by | ||||
| # the Free Software Foundation, either version 3 of the License, or | ||||
| # (at your option) any later version. | ||||
| # | ||||
| # This program is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| # GNU General Public License for more details. | ||||
| # | ||||
| # You should have received a copy of the GNU General Public License | ||||
| # along with this program.  If not, see <https://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| import time | ||||
| import tabulate | ||||
| from tabulate import tabulate | ||||
| 
 | ||||
| tabulate.PRESERVE_WHITESPACE = True | ||||
| 
 | ||||
| 
 | ||||
| class TimerMetrics: | ||||
|     """Timer Metrics | ||||
| 
 | ||||
|     This leverages the timer module to provide a lightweight set of timer | ||||
|     utilities, to keep track of how long specific sub-processes in a Python | ||||
|     program are taking. | ||||
| 
 | ||||
|     Data structure: | ||||
|     { | ||||
|         "Timer name": { | ||||
|             "running": True, | ||||
|             "start_time": 123.4, | ||||
|             "total_time": 0.0 | ||||
|         } | ||||
|     } | ||||
|     """ | ||||
| 
 | ||||
|     def __init__(self): | ||||
|         # Store the data in a dictionary | ||||
|         self.data = {} | ||||
| 
 | ||||
|     def start(self, name): | ||||
|         """Start a timer with a given name | ||||
| 
 | ||||
|         This records the current time and adds a new entry. If the entry | ||||
|         already exists and the timer is not running, start it up again. If | ||||
|         the entry exists and the timer is already running, do nothing. | ||||
|         """ | ||||
| 
 | ||||
|         # Get a timer value ASAP | ||||
|         t_val = time.perf_counter() | ||||
| 
 | ||||
|         # If it isn't already there, create an entry | ||||
|         if name not in self.data: | ||||
|             # Initialize the entry | ||||
|             self.data[name] = {} | ||||
| 
 | ||||
|             # Make sure it is running | ||||
|             self.data[name]["running"] = True | ||||
| 
 | ||||
|             # Put our times in there | ||||
|             self.data[name]["start_time"] = t_val | ||||
|             self.data[name]["total_time"] = 0.0 | ||||
| 
 | ||||
|         # If it is there, only act if it's running | ||||
|         elif self.data[name]["running"] == False: | ||||
|             # Now we're running | ||||
|             self.data[name]["running"] = True | ||||
| 
 | ||||
|             # Change our start time as well | ||||
|             self.data[name]["start_time"] = t_val | ||||
| 
 | ||||
|     def stop(self, name): | ||||
|         """Stop a timer with the given name | ||||
| 
 | ||||
|         This stops the timer if it is running. If there is no such timer | ||||
|         currently running, throw an error. If the timer exists and is running, | ||||
|         stop it and update total_time. If the timer exists but isn't running, | ||||
|         do nothing. | ||||
|         """ | ||||
| 
 | ||||
|         # Get a timer value ASAP | ||||
|         t_val = time.perf_counter() | ||||
| 
 | ||||
|         # Raise an error if the timer doesn't exist | ||||
|         if name not in self.data: | ||||
|             assert ValueError("Timer " + name + " not found") | ||||
| 
 | ||||
|         # If the timer is running, update total_time and stop it | ||||
|         if self.data[name]["running"] == True: | ||||
|             # Stop the timer | ||||
|             self.data[name]["running"] = False | ||||
| 
 | ||||
|             # Get the current time and add it to any existing time, which | ||||
|             # may indeed exist | ||||
|             cur_time = t_val - self.data[name]["start_time"] | ||||
|             self.data[name]["total_time"] += cur_time | ||||
| 
 | ||||
|     def display(self): | ||||
|         """Print a pretty(-ish) table with all of the data in it""" | ||||
| 
 | ||||
|         # Initialize the dict for the table we're going to render | ||||
|         # The dict keys are the headers | ||||
|         table = {} | ||||
| 
 | ||||
|         # Simplify the data with just the times and the timer labels | ||||
|         pretty = {} | ||||
|         for item in self.data: | ||||
|             pretty[item] = self.data[item]["total_time"] | ||||
| 
 | ||||
|         # Sort the data into descending order and then put them into two lists | ||||
|         # Keys have one list and values have another | ||||
|         s_pretty = {k: v for k, v in sorted(pretty.items(), key=lambda item: item[1], reverse=True)} | ||||
|         table["Timer"] = list(s_pretty.keys()) | ||||
|         table["Seconds"] = list(s_pretty.values()) | ||||
| 
 | ||||
|         # Get a total second count | ||||
|         total_secs = 0.0 | ||||
|         for i in range(len(table["Seconds"])): | ||||
|             total_secs += table["Seconds"][i] | ||||
| 
 | ||||
|         # Add the totals to the table | ||||
|         table["Timer"].append("Total Time") | ||||
|         table["Seconds"].append(total_secs) | ||||
| 
 | ||||
|         # Get percentages in its own column | ||||
|         table["% of total"] = [] | ||||
|         for i in range(len(table["Seconds"])): | ||||
|             percent = ( table["Seconds"][i] / total_secs ) * 100.0 | ||||
|             # Round to the nearest hundredth and add a % | ||||
|             table["% of total"].append(str(round(percent, 2)) + "%") | ||||
| 
 | ||||
|         # Show the pretty table | ||||
|         print(tabulate(table, headers="keys", tablefmt="grid")) | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user