MODULES

Timer

Utilities to measure time from system and custom clocks/counters.

Classes:

Todo

  • Extend to support additional stats besides time (e.g. psutil).
  • Support timing concurrent processes, use time.thread_time() (requires Python 3.7).
class smarttimer.timer.TimerDict(tdict={})[source]

Map between label identifier and callable object.

Parameters:

tdict (dict, TimerDict, optional) – Dictionary for initialization.

Raises:
update(tdict)[source]

Extends map with given dictionary.

Only accepts dict or TimerDict arguments.

class smarttimer.timer.Timer(label='', **kwargs)[source]

Read current time from a clock/counter.

Parameters:
  • label (str, optional) – Label identifier. Default is empty string.
  • seconds (float, optional) – Time measured in fractional seconds. Default is 0.0.
  • clock_name (str, optional) – Clock name used to select a time measurement function. Default is DEFAULT_CLOCK_NAME.
  • timer (dict, TimerDict, optional) – Timer for initialization.

A Timer allows recording the current time measured by a registered timing function. Time is recorded in fractional seconds and fractional minutes. Timer supports addition, difference, and logical operators. Timer uses a simple and extensible API which allows registering new timing functions. A timing function is compliant if it returns a time measured in fractional seconds. The function can contain arbitrary positional and/or keyword arguments or no arguments.

Timer API examples.
 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
from smarttimer import Timer

# Find the current time function of a Timer
t1 = Timer('Timer1')
print(Timer.CLOCKS[t1.clock_name])
# or
Timer.print_clocks()
print(t1.clock_name)

# Change current time function
t1.clock_name = 'process_time'

# Record a time measurement
t1.time()
print(t1)

# Create another Timer compatible with 'Timer1'
t2 = Timer('Timer2', clock_name='process_time')
t2.print_info()
t2.time()
print(t2)

# Sum Timers
t3 = Timer.sum(t1, t2)
# or
t3 = t1 + t2
print(t3)

# Find difference between Timers
t4 = Timer.diff(t1, t2)
# or
t4 = t2 - t1
print(t4)

# Compare Timers
print(t1 == t2)  # False
print(t2 > t1)   # True
print(t4 <= t3)  # True
Available time measurement functions in CLOCKS
Registering a new time measurement function.
def custom_time_function(*args, **kwargs):
    # Measure time
    time_in_some_unit = ...

    # Convert time to fractional seconds
    time_seconds = time_in_some_unit ...
    return time_seconds

# Register custom_time_function() as 'custom_time'
Timer.register_clock('custom_time', custom_time_function)
# or
Timer.CLOCKS['custom_time'] = custom_time_function

Note

  • New timing functions need to have a compliant interface. If a user wants to register a non-compliant timing function, a compliant wrapper function can be used. The available timing functions are built-ins from the standard time library.
  • Only Timers with compatible clocks support arithmetic and logical operators. Otherwise a TimerCompatibilityError exception occurs.

Warning

When registering a new timing function to CLOCKS, it is recommended to use a unique clock name to prevent overwriting over an existing one.

DEFAULT_CLOCK_NAME

str – Default clock name, used when clock_name is empty string.

Raises:TimerTypeError – If not a string.
CLOCKS

TimerDict, str -> callable – Map between clock name and time measurement functions.

Raises:
label

str – Label identifier.

Raises:TimerTypeError – If not a string.
seconds

float – Time measured in fractional seconds (read-only).

Set internally either during initialization or when recording time.

Raises:
minutes

float – Time measured in minutes (read-only).

clock_name

str – Clock name used to select a time measurement function.

Indexes the CLOCKS map to select a time function. If set to the empty string then DEFAULT_CLOCK_NAME is used. An instance is reset when set to a new and incompatible clock name.

Raises:TimerTypeError – If not a string.
__str__()[source]

String representation.

Returns:
Comma delimited string (seconds,
minutes, label)
Return type:str
time(*args, **kwargs)[source]

Invoke time measurement function and record measured time.

Calls timing function currently configured via clock_name. This method accepts arbitrary positional and/or keyword arguments to enable support for arbitrary signatures of timing functions.

Parameters:
  • args (tuple, optional) – Positional arguments for time function.
  • kwargs (dict, optional) – Keyword arguments for time function.
Returns:

Time measured in fractional seconds.

Return type:

float

reset()[source]

Reset the clock instance to default values.

clear()[source]

Set time values to zero.

get_info()[source]

Return clock information.

For clock_name that can be queried with time.get_clock_info, forward the output namespace object. Otherwise create and populate a namespace with the timing function.

Returns:Namespace with clock info.
Return type:types.SimpleNamespace
print_info()[source]

Pretty print clock information.

is_compatible(other)[source]

Return truth of compatibility between a Timer pair.

For a clock_name that can be queried with time.get_clock_info, compatibility requires that all attributes are identical. All other cases require that the timing functions are the same function.

Parameters:other (Timer) – Second instance.
Returns:True if compatible, else False.
Return type:bool
classmethod sum(timer1, timer2)[source]

Compute the time sum of a Timer pair.

This method wraps the addition operator between Timer objects. The label of the resulting Timer contains a combination of timer1 and timer2 label. The clock_name of the resulting Timer is set to the clock name of timer1.

Parameters:
  • timer1 (Timer) – First instance.
  • timer2 (Timer) – Second instance.
Returns:

Instance containing the time sum.

Return type:

Timer

Raises:

TimerCompatibilityError – If not compatible.

classmethod diff(timer1, timer2)[source]

Compute the absolute time difference of a Timer pair.

This method wraps the difference operator between Timer objects. The label of the resulting Timer contains a combination of timer1 and timer2 label. The clock_name of the resulting Timer is set to the clock name of timer1.

Parameters:
  • timer1 (Timer) – First instance.
  • timer2 (Timer) – Second instance.
Returns:

Instance containing the absolute time difference.

Return type:

Timer

Raises:

TimerCompatibilityError – If not compatible.

classmethod register_clock(clock_name, clock_func)[source]

Registers a time function to CLOCKS map.

If a mapping already exists for clock_name, it will be updated with clock_func. For invalid arguments, error handling is expected from CLOCKS properties.

Parameters:
  • clock_name (str) – Clock name.
  • clock_func (callable) – Reference to a time measurement function.
classmethod unregister_clock(clock_name)[source]

Remove a registered clock from CLOCKS map.

For invalid arguments, error handling is expected from CLOCKS properties.

Parameters:clock_name (str) – Clock name.
classmethod print_clocks()[source]

Pretty print information of registered clocks.

class smarttimer.timer.MetaTimerProperty[source]

Metaclass for Timer class variables.

Requires TimerDict.

Raises:TimerTypeError – If set property uses an invalid type.
class smarttimer.timer.TimerDict(tdict={})[source]

Map between label identifier and callable object.

Parameters:

tdict (dict, TimerDict, optional) – Dictionary for initialization.

Raises:

SmartTimer

SmartTimer

Classes:
SmartTimer
class smarttimer.smarttimer.SmartTimer(name='smarttimer', **kwargs)[source]

Manager of Timer measurements for code blocks.

Supports the following schemes of timed blocks:
  • Consecutive: tic(), toc(), …, tic(), toc()
  • Nested: tic(), tic(), …, toc(), toc()
  • Cascade: tic(), toc(), toc(), …
  • Nested interleaved: tic(), tic(), toc(), tic(), …, toc(), toc()
  • Key-paired: tic(‘outer’), tic(‘inner’), …, toc(‘outer’), toc()
labels

Lists of time labels for completed blocks.

Returns:Labels of completed blocks.
Return type:list
active_labels

Lists of time labels for active blocks.

Returns:Labels of blocks without a matching toc().
Return type:list
seconds

List of seconds elapsed for completed blocks.

Returns:Time in seconds.
Return type:list
minutes

List of minutes elapsed for completed blocks.

Returns:Time in minutes.
Return type:list
times

Dictionary of times elapsed for completed blocks.

Returns:Keys are labels and values list of time in seconds.
Return type:list
__getitem__(*keys)[source]

Use dictionary syntax to access time in seconds

The values returned correspond to the time in seconds. Multiple values are returned as a list, generally in the same order as the given keys (except for cases where duplicate labels exist).

Note

  • If key is string, then consider it as a label
  • If key is integer or slice, then consider it as an index
  • Key types can be mixed

Example

timer[4, 2] timer[‘I/O’, ‘Processing’] timer[2, ‘Processing’] timer[1:2, 4:6]

remove(*keys)[source]

Remove a Timer.

Note

  • Remove from timers, not stack
  • If key is string, then consider it as a label
  • If key is integer or slice, then consider it as an index
  • Key types can be mixed
clear()[source]

Set time values to zero.

walltime()[source]

Compute walltime in seconds.

Only supported when all timers have completed, else error occurs.

tic(key='')[source]

Start measuring time.

Measure time at the latest moment possible to not minimize noise from internal operations.

toc(key=None)[source]

Stop measuring time.

Measure time at the soonest moment possible to not minimize noise from internal operations.

Note

  • In cascade regions, that is, multiple toc() calls, some noise will be introduced. There is the possibility of correcting this noise, but even the correction is noise itself.
write_to_file(fn='', flag='w')[source]

Save timer contents to a file.

The flag argument controls if the file is overwritten or append.

Timer Exceptions

class smarttimer.timer.TimerTypeError(msg_or_name='', dtype=None)[source]

Exception for invalid data type assigment in Timer.

class smarttimer.timer.TimerValueError(msg_or_name='', dtype=None)[source]

Exception for invalid values in Timer.

class smarttimer.timer.TimerKeyError(msg_or_name='', dtype=None)[source]

Exception for invalid key indexing in TimerDict.

class smarttimer.timer.TimerCompatibilityError(message='')[source]

Exception for incompatible Timer instances.

Parameters:message (str, optional) – Error message.