muutils.timeit_fancy
timeit_fancy
is just a fancier version of timeit with more options
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):
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)
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:
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 totimeit.Timer
as thestmt
argument.setup: str
The setup code to run beforecmd
. If a string, it will be passed totimeit.Timer
as thesetup
argument.repeats: int
The number of times to runcmd
to get a reliable measurement.namespace: dict[str, Any]
Passed totimeit.Timer
constructor. Ifcmd
orsetup
use local or global variables, they must be passed here. Seetimeit
documentation for details.get_return: bool
Whether to pass the value returned fromcmd
. If True, the return value will be appended in a tuple with execution time. This is for speed and convenience so thatcmd
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 apstats.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 runcmd
the minimum number of times to get a reliable measurement.return_value: T|None
The return value ofcmd
ifget_return
isTrue
, otherwiseNone
.profile: pstats.Stats|None
Apstats.Stats
object ifdo_profiling
isTrue
, otherwiseNone
.