Time your python scripts easily and with style. This tool uses fslog
to format its output.
The same classes can be used either through with
or as a @decorator
.
pip install horatio
import horatio
import fslog
import time
@horatio.section("Factorial computation", tail="{0} took {1}")
def fact(n):
if n == 1:
fslog.log("Reached base case")
return 1
fslog.log("This is not the base case")
with horatio.step("Sleeping for a second"):
time.sleep(1)
res = n * fact(n-1)
return res
@horatio.section()
def main():
fact(4)
main()
Will produce the following output:
ββ main
β ββ Factorial computation
β β This is not the base case
β β Sleeping for a second ... done in 1.005s
β β ββ Factorial computation
β β β This is not the base case
β β β Sleeping for a second ... done in 1.003s
β β β ββ Factorial computation
β β β β This is not the base case
β β β β Sleeping for a second ... done in 1.004s
β β β β ββ Factorial computation
β β β β β Reached base case
β β β β ββ Factorial computation took < 1 ms
β β β ββ Factorial computation took 1.005s
β β ββ Factorial computation took 2.009s
β ββ Factorial computation took 3.014s
ββ main: 3.015s
It's useful when timing complex code with nested calls to other timed functions. When used as a decorator with no arguments it uses the function name as a description of the section.
As a decorator:
@horatio.section():
def inv(A):
return np.linalg.inv(A)
As a context:
@horatio.section()
def parse(file_name):
fslog.log("File name:", file_name)
return None
@horatio.section()
def count_words(d):
return 0
@horatio.section()
def main():
d = parse("words.txt")
n = count_words(d)
fslog.log(n)
Will produce something like
ββ main
β ββ parse
β β File name: words.txt
β ββ parse: 123ms
β ββ count_words
β ββ count_words: 4.567s
ββ main: 4.701s
Prints the description and the elapsed time in the same line. It is suggested for code sections that don't print any output.
As a context:
with horatio.step("Inverting the matrix"):
B = np.linalg.inv(A)
As a decorator:
@horatio.step("Inverting the matrix"):
def inv(A):
return np.linalg.inv(A)
Will produce something like Invering the matrix ... done in 123ms
.
It's useful when timing code that prints text and we want the output to be flat (no indentation).
As a decorator:
@horatio.flat():
def inv(A):
return np.linalg.inv(A)
As a context:
with horatio.flat("inv"):
B = np.linalg.inv(A)
Will produce something like
[*] inv
[*] inv: 123ms
To get a customized time format just pass a fmt
argument when calling
Horatio's functions, or set it everywhere with horatio.fmt
.
Time is formatted automatically if fmt=None
.
Here are the complete list of time symbols:
Symbol | Meaning |
---|---|
{f} |
Total seconds with millisecond precision |
{ms} |
Total milliseconds |
{s} |
Total seconds |
{m} |
Total minutes |
{h} |
Total hours |
{S} |
Seconds of a day-hour-min-sec-like format |
{M} |
Minutes of a day-hour-min-sec-like format |
{H} |
Hours of a day-hour-min-sec-like format |
{D} |
Days of a day-hour-min-sec-like format |
Some examples:
horatio.section(fmt="minutes={m} seconds={s}")
horatio.fmt="{D} days {H:02}:{M:02}:{S:02}"