docs for muutils v0.6.17
View Source on GitHub

# muutils.timeit_fancy

`timeit_fancy` is just a fancier version of timeit with more options

View Source
View on GitHub

      1"`timeit_fancy` is just a fancier version of timeit with more options"
      2
      3from __future__ import annotations
      4
      5import pstats
      6import timeit
      7import cProfile
      8from typing import Callable, Union, TypeVar, NamedTuple, Any
      9import warnings
     10
     11from muutils.statcounter import StatCounter
     12
     13T = TypeVar("T")
     14
     15
     16class FancyTimeitResult(NamedTuple):
     17    """return type of `timeit_fancy`"""
     18
     19    timings: StatCounter
     20    return_value: T  # type: ignore[valid-type]
     21    profile: Union[pstats.Stats, None]
     22
     23
     24def timeit_fancy(
     25    cmd: Callable[[], T],
     26    setup: Union[str, Callable[[], Any]] = lambda: None,
     27    repeats: int = 5,
     28    namespace: Union[dict[str, Any], None] = None,
     29    get_return: bool = True,
     30    do_profiling: bool = False,
     31) -> FancyTimeitResult:
     32    """
     33    Wrapper for `timeit` to get the fastest run of a callable with more customization options.
     34
     35    Approximates the functionality of the %timeit magic or command line interface in a Python callable.
     36
     37    # Parameters
     38
     39    - `cmd: Callable[[], T] | str`
     40        The callable to time. If a string, it will be passed to `timeit.Timer` as the `stmt` argument.
     41    - `setup: str`
     42        The setup code to run before `cmd`. If a string, it will be passed to `timeit.Timer` as the `setup` argument.
     43    - `repeats: int`
     44        The number of times to run `cmd` to get a reliable measurement.
     45    - `namespace: dict[str, Any]`
     46        Passed to `timeit.Timer` constructor.
     47        If `cmd` or `setup` use local or global variables, they must be passed here. See `timeit` documentation for details.
     48    - `get_return: bool`
     49        Whether to pass the value returned from `cmd`. If True, the return value will be appended in a tuple with execution time.
     50        This is for speed and convenience so that `cmd` doesn't need to be run again in the calling scope if the return values are needed.
     51        (default: `False`)
     52    - `do_profiling: bool`
     53        Whether to return a `pstats.Stats` object in addition to the time and return value.
     54        (default: `False`)
     55
     56    # Returns
     57
     58    `FancyTimeitResult`, which is a NamedTuple with the following fields:
     59
     60    - `time: float`
     61        The time in seconds it took to run `cmd` the minimum number of times to get a reliable measurement.
     62    - `return_value: T|None`
     63        The return value of `cmd` if `get_return` is `True`, otherwise `None`.
     64    - `profile: pstats.Stats|None`
     65        A `pstats.Stats` object if `do_profiling` is `True`, otherwise `None`.
     66    """
     67    timer: timeit.Timer = timeit.Timer(cmd, setup, globals=namespace)
     68
     69    # Perform the timing
     70    times: list[float] = timer.repeat(repeats, 1)
     71
     72    # Optionally capture the return value
     73    profile: pstats.Stats | None = None
     74
     75    return_value: T | None = None
     76    if get_return or do_profiling:
     77        # Optionally perform profiling
     78        if do_profiling:
     79            profiler = cProfile.Profile()
     80            profiler.enable()
     81
     82        try:
     83            return_value = cmd()
     84        except TypeError as e:
     85            warnings.warn(
     86                f"Failed to get return value from `cmd` due to error (probably passing a string). will return `return_value=None`\n{e}",
     87            )
     88
     89        if do_profiling:
     90            profiler.disable()
     91            profile = pstats.Stats(profiler).strip_dirs().sort_stats("cumulative")
     92
     93    # reset the return value if it wasn't requested
     94    if not get_return:
     95        return_value = None
     96
     97    return FancyTimeitResult(
     98        timings=StatCounter(times),
     99        return_value=return_value,
    100        profile=profile,
    101    )

class FancyTimeitResult(typing.NamedTuple):
View Source
View on GitHub

    17class FancyTimeitResult(NamedTuple):
    18    """return type of `timeit_fancy`"""
    19
    20    timings: StatCounter
    21    return_value: T  # type: ignore[valid-type]
    22    profile: Union[pstats.Stats, None]

return type of `timeit_fancy`

FancyTimeitResult( timings: ForwardRef('StatCounter'), return_value: ForwardRef('T'), profile: ForwardRef('Union[pstats.Stats, None]'))

Create new instance of FancyTimeitResult(timings, return_value, profile)

timings: muutils.statcounter.StatCounter

Alias for field number 0

return_value: ~T

Alias for field number 1

profile: Optional[pstats.Stats]

Alias for field number 2

##### Inherited Members

builtins.tuple
  index
  count

def timeit_fancy( cmd: Callable[[], ~T], setup: Union[str, Callable[[], Any]] = <function <lambda>>, repeats: int = 5, namespace: Optional[dict[str, Any]] = None, get_return: bool = True, do_profiling: bool = False) -> FancyTimeitResult:
View Source
View on GitHub

     25def timeit_fancy(
     26    cmd: Callable[[], T],
     27    setup: Union[str, Callable[[], Any]] = lambda: None,
     28    repeats: int = 5,
     29    namespace: Union[dict[str, Any], None] = None,
     30    get_return: bool = True,
     31    do_profiling: bool = False,
     32) -> FancyTimeitResult:
     33    """
     34    Wrapper for `timeit` to get the fastest run of a callable with more customization options.
     35
     36    Approximates the functionality of the %timeit magic or command line interface in a Python callable.
     37
     38    # Parameters
     39
     40    - `cmd: Callable[[], T] | str`
     41        The callable to time. If a string, it will be passed to `timeit.Timer` as the `stmt` argument.
     42    - `setup: str`
     43        The setup code to run before `cmd`. If a string, it will be passed to `timeit.Timer` as the `setup` argument.
     44    - `repeats: int`
     45        The number of times to run `cmd` to get a reliable measurement.
     46    - `namespace: dict[str, Any]`
     47        Passed to `timeit.Timer` constructor.
     48        If `cmd` or `setup` use local or global variables, they must be passed here. See `timeit` documentation for details.
     49    - `get_return: bool`
     50        Whether to pass the value returned from `cmd`. If True, the return value will be appended in a tuple with execution time.
     51        This is for speed and convenience so that `cmd` doesn't need to be run again in the calling scope if the return values are needed.
     52        (default: `False`)
     53    - `do_profiling: bool`
     54        Whether to return a `pstats.Stats` object in addition to the time and return value.
     55        (default: `False`)
     56
     57    # Returns
     58
     59    `FancyTimeitResult`, which is a NamedTuple with the following fields:
     60
     61    - `time: float`
     62        The time in seconds it took to run `cmd` the minimum number of times to get a reliable measurement.
     63    - `return_value: T|None`
     64        The return value of `cmd` if `get_return` is `True`, otherwise `None`.
     65    - `profile: pstats.Stats|None`
     66        A `pstats.Stats` object if `do_profiling` is `True`, otherwise `None`.
     67    """
     68    timer: timeit.Timer = timeit.Timer(cmd, setup, globals=namespace)
     69
     70    # Perform the timing
     71    times: list[float] = timer.repeat(repeats, 1)
     72
     73    # Optionally capture the return value
     74    profile: pstats.Stats | None = None
     75
     76    return_value: T | None = None
     77    if get_return or do_profiling:
     78        # Optionally perform profiling
     79        if do_profiling:
     80            profiler = cProfile.Profile()
     81            profiler.enable()
     82
     83        try:
     84            return_value = cmd()
     85        except TypeError as e:
     86            warnings.warn(
     87                f"Failed to get return value from `cmd` due to error (probably passing a string). will return `return_value=None`\n{e}",
     88            )
     89
     90        if do_profiling:
     91            profiler.disable()
     92            profile = pstats.Stats(profiler).strip_dirs().sort_stats("cumulative")
     93
     94    # reset the return value if it wasn't requested
     95    if not get_return:
     96        return_value = None
     97
     98    return FancyTimeitResult(
     99        timings=StatCounter(times),
    100        return_value=return_value,
    101        profile=profile,
    102    )

Wrapper for `timeit` to get the fastest run of a callable with more customization options.

Approximates the functionality of the %timeit magic or command line interface in a Python callable.

# Parameters

- `cmd: Callable[[], T] | str` The callable to time. If a string, it will be passed to `timeit.Timer` as the `stmt` argument.
- `setup: str` The setup code to run before `cmd`. If a string, it will be passed to `timeit.Timer` as the `setup` argument.
- `repeats: int` The number of times to run `cmd` to get a reliable measurement.
- `namespace: dict[str, Any]` Passed to `timeit.Timer` constructor. If `cmd` or `setup` use local or global variables, they must be passed here. See `timeit` documentation for details.
- `get_return: bool` Whether to pass the value returned from `cmd`. If True, the return value will be appended in a tuple with execution time. This is for speed and convenience so that `cmd` doesn't need to be run again in the calling scope if the return values are needed. (default: `False`)
- `do_profiling: bool` Whether to return a `pstats.Stats` object in addition to the time and return value. (default: `False`)

# Returns

`FancyTimeitResult`, which is a NamedTuple with the following fields:

- `time: float` The time in seconds it took to run `cmd` the minimum number of times to get a reliable measurement.
- `return_value: T|None` The return value of `cmd` if `get_return` is `True`, otherwise `None`.
- `profile: pstats.Stats|None` A `pstats.Stats` object if `do_profiling` is `True`, otherwise `None`.