File size: 4,822 Bytes
068ed60 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
"""
Module execution_timer provides an ExecutionTimer class
to measure the execution time of a code block.
It offers two usage options: as a context manager and as a decorator.
* Example usage as a context manager:
with ExecutionTimer():
main()
* Example usage as a decorator:
@execution_timer
def main():
# Code block to measure execution time
"""
from datetime import datetime
from time import perf_counter_ns
from dataclasses import dataclass
from rich.console import Console
@dataclass(slots=True)
class ExecutionTimer:
"""
ExecutionTimer is a context manager that measures the execution time of a code block.
It captures the start time, end time, and duration of the code block.
"""
start_date: datetime = None
end_date: datetime = None
start_time_ns: int = None
end_time_ns: int = None
console: Console = Console()
def __post_init__(self):
self.start_date = datetime.now()
self.start_time_ns = perf_counter_ns()
def __enter__(self) -> 'ExecutionTimer':
return self
def __exit__(self, exc_type, exc_val, exc_tb):
try:
self.end_date = datetime.now()
self.end_time_ns = perf_counter_ns()
self.display_time()
except AttributeError:
print('An error occurred: __exit__')
@staticmethod
def current_datetime(date: datetime) -> str:
"""
Formats a datetime object as a string in the format 'YYYY-MM-DD HH:MM:SS'.
"""
return f'[yellow]{date.year}-{date.month:02d}-{date.day:02d}' \
f' [white bold]{date.hour:02d}:{date.minute:02d}:{date.second:02d}'
def calculate_duration(self) -> str:
"""
Calculates the duration of the code block in hours, minutes, seconds, milliseconds,
microseconds, and nanoseconds.
"""
duration_ns: int = self.end_time_ns - self.start_time_ns
duration_s, duration_ns = map(int, divmod(duration_ns, 1_000_000_000))
duration_ms, duration_ns = map(int, divmod(duration_ns, 1_000_000))
duration_us, duration_ns = map(int, divmod(duration_ns, 1_000))
hours, remainder = map(int, divmod(duration_s, 3600))
minutes, seconds = map(int, divmod(remainder, 60))
return f'[white bold]{hours:02d}:{minutes:02d}:{seconds:02d}:' \
f'{duration_ms:03d}:{duration_us:03d}:{duration_ns:03d}'
def calculate_duration_alt(self) -> tuple[float, ...]:
"""
Calculates the duration of the code block in hours, minutes, and seconds
using an alternative method.
"""
duration_ns: int = self.end_time_ns - self.start_time_ns
hours_alt: float = duration_ns / 1_000_000_000 / 60 / 60
minutes_alt: float = duration_ns / 1_000_000_000 / 60
seconds_alt: float = duration_ns / 1_000_000_000
return hours_alt, minutes_alt, seconds_alt
def display_time(self):
"""
Displays the start date, end date, and duration of the code block execution.
"""
start_date_str: str = self.current_datetime(self.start_date)
end_date_str: str = self.current_datetime(self.end_date)
duration: str = self.calculate_duration()
hours_alt, minutes_alt, seconds_alt = map(
float, self.calculate_duration_alt())
self.console.print(
'\n[bold white]ββββββββββββ EXECUTION TIME ββββββββββββ')
self.console.print(
'[bold bright_yellow] YYYY-MM-DD HH:MM:SS:ms :Β΅s :ns')
self.console.print(
f'[bright_red bold][[bold white]START[bright_red bold]] {start_date_str}')
self.console.print(
f'[bright_red bold][[bold white]END[bright_red bold]] {end_date_str}')
self.console.print(
f'[bright_red bold][[bold white]TIME[bright_red bold]] [bold bright_yellow]YYYY-MM-DD {duration}')
self.console.print('[bright_red bold] ^^^^^^^^^^^^')
self.console.print(
f'[bright_red bold][[bold white]TIME[bright_red bold]] [white bold]{hours_alt:.9f} hours')
self.console.print(
f'[bright_red bold][[bold white]TIME[bright_red bold]] [white bold]{minutes_alt:.9f} minutes')
self.console.print(
f'[bright_red bold][[bold white]TIME[bright_red bold]] [white bold]{seconds_alt:.9f} seconds')
def execution_timer(func):
"""
Decorator that measures the execution time of a function using ExecutionTimer.
"""
def wrapper(*args, **kwargs):
with ExecutionTimer():
result = func(*args, **kwargs)
return result
return wrapper
|