-
Notifications
You must be signed in to change notification settings - Fork 0
.time_it()
Available from StaticTimer and Timer, with the difference being that the static version will output or return any results immediately, while the non-static version will store the measured times for graphing, output, or best-fit-curve determination at a later time. The main and first parameter to time_it() must be either a string or a callable. If it is a callable, then it will be timed in the same manner as a function wrapped by .decorate(). Otherwise, eval() will be used to evaluate the string.
Note: There are several reasons why it might be preferable to use .time_it() over .decorate()
- You're trying to time a string or a function that you can't decorate, like a built-in function
- You're timing the function in a production setting and cannot leave a decorator on the function
- You're timing an anonymous function
Note: .time_it() can take an argument called copiers which is either a function or a map of argument indices/names to functions. These functions are used to copy the argument before it is passed into the wrapped function on each iteration. This can be helpful, for example, if your function has side-effects and modifies the parameters. A prime example would be an in-place sorting function. If the list isn't copied, then subsequent iterations will be passed an already sorted list which could skew the results. In that case, copiers=list could be used to ensure that the wrapped function is getting a copy and not the original. Passing copiers only makes sense when a function is being timed.
Note: .time_it() can take an argument called setup which is a string. Passing setup only makes sense if a string is being evaluated. setup will be executed once before the string is evaluated and can be used to introduce names into the namespace that are needed by the code in the string being evaluated. Names can also be passed in by setting globals and locals.
a = StaticTimer.time_it("2**64", runs=1000, iterations_per_run=10, time_unit=StaticTimer.US)
b = StaticTimer.time_it("1<<64", runs=1000, iterations_per_run=10, time_unit=StaticTimer.US)
c = StaticTimer.time_it("pow(2, 64)", runs=1000, iterations_per_run=10, time_unit=StaticTimer.US)
print(a == b == c == 2**64)
# 68.24003 us - 2**64 [runs=1000, iterations= 10]
# 64.60341 us - 1<<64 [runs=1000, iterations= 10]
# 90.18227 us - pow(2, 64) [runs=1000, iterations= 10]
# True.time_it(), and .decorate() for that matter, will return the result of calling the function or evaluating the string. Additionally, any output will label the run as either callable.__name__ or the string itself. In the case above, iterations_per_run is set to 10 as the measured time of one run is very small, around 7.6 us. The accuracy of the clock ExecTiming is using internally can depend on the computer it is being run on, so small times can be more inaccurate on some systems. To combat this, the time can be made longer by calling or evaluating multiple times before measuring how much time has passed.