Skip to content

Commit

Permalink
Add capability to return pyxx.debugging.TimeIT timer duration
Browse files Browse the repository at this point in the history
  • Loading branch information
nathan-hess committed Dec 12, 2023
1 parent 33aeecd commit f387f42
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 18 deletions.
1 change: 1 addition & 0 deletions docs/source/_templates/api_reference_class_template.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
np
num
TextFile
TimeIt
TypedList
TypedListWithID
UnitConverter
Expand Down
68 changes: 50 additions & 18 deletions pyxx/debugging/classes/timer.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,35 +22,49 @@ class TimeIt:
Examples
--------
Time a code block and print the duration to the terminal:
.. code-block:: python
>>> from pyxx.debugging import TimeIt
>>> import time
>>> with TimeIt(units='ms', message='Execution time: {time:.2f} {units}'):
... # Code block of which to measure the duration
... time.sleep(1)
Execution time: 1000.10 ms
Time a code block and store the duration in a variable:
.. code-block:: python
>>> from pyxx.debugging import TimeIt
>>> import time
>>> with TimeIt(units='ms', message='Execution time: {time} {units}'):
>>> timer = TimeIt(print_duration=False)
>>> with timer:
... # Code block of which to measure the duration
... time.sleep(1)
Execution time: 1000.1010101010101 ms
>>> print(timer.duration('ms'))
1000.1010101010101
"""

def __init__(self, units: str = 's',
def __init__(self, print_duration: bool = True, units: str = 's',
message: str = 'Command duration: {time} {units}') -> None:
"""Creates a new context manager for measuring the duration of a code block
Parameters
----------
print_duration : bool, optional
Whether to print to the terminal the duration of the code block
units : str, optional
The units in which the duration will be displayed (default is ``'s'``)
Only applicable if ``print_duration`` is ``True``. Specifies the
units in which the duration will be displayed to the terminal
(default is ``'s'``)
message : str, optional
The message template to display the duration (default is
Only applicable if ``print_duration`` is ``True``. The message
template to display the duration (default is
``'Command duration: {time} {units}'``). The ``{time}`` and
``{units}`` placeholders will be replaced by the duration and
units, respectively
Raises
------
ValueError
If the specified units are invalid and cannot be converted from
seconds
"""
self.__unit_converter = UnitConverterSI()

Expand All @@ -59,18 +73,36 @@ def __init__(self, units: str = 's',
raise ValueError(
f'Invalid units: cannot convert from seconds to "{units}"')

self.__print = bool(print_duration)
self.__units = units
self.__message = message

self.__t0 = 0.0
self.__t0_s = 0.0
self.__dt_s = 0.0

def __enter__(self) -> None:
self.__t0 = time.time()
self.__t0_s = time.time()

def __exit__(self, *args, **kwargs) -> None:
t1 = time.time()
duration = self.__unit_converter.convert(quantity=t1 - self.__t0,
from_unit='s',
to_unit=self.__units)
t1_s = time.time()

# Calculate duration in seconds
self.__dt_s = t1_s - self.__t0_s

if self.__print:
duration = self.__unit_converter.convert(
quantity=self.__dt_s, from_unit='s', to_unit=self.__units)

print(self.__message.format(time=duration, units=self.__units))

print(self.__message.format(time=duration, units=self.__units))
def duration(self, units: str = 's') -> float:
"""Returns the last measured duration from the context manager
Parameters
----------
units : str
The units in which to return the duration (default is ``'s'``)
"""
return self.__unit_converter.convert(
quantity=self.__dt_s, from_unit='s', to_unit=units
)

0 comments on commit f387f42

Please sign in to comment.