Package: pretty-timeit
ptimeittimeit, but with the interface it should have had.Why did I write this?timeit is a great module, but whenever I wanted to use it, I had to look up the syntax, and even after that it was tricky to get things working. I wanted something that had the similar functionality of timeit but an easier, more intuitive syntax.Under the hood, I take the same approach as timeit does-Everything is imported once.The garbage collector is disabled when the function is run.By default the function runs 1 milllion times.InstallationWith pip.$pipinstallpretty-timeitWith poetry.$poetryaddpretty-timeitUsage.A simple example.fromptimeitimporttimethis,Timer# although this is a decorator, your original function will not be modified.@timethis()deffunction_to_be_timed():lst=[iforiinrange(10)]Timer.run()# Call this at the end of the file.outputname                 | Execution timefunction_to_be_timed | 0.5608107Note: By defaultTimer.run()Prints the results to the console.
If you want it to return a string, do this.Timer.run(print_results=False)# returns a stringMixing positional arguments with keyword arguments.Positional Arguments must be passed inside a list even if there is one argument.Keyword arguments must be passed inside a dictionary.Note the order follows the common idiom offunction(*args, **kwargs).@timethis([10],{"second_count_up_to":10})deffunction_to_be_timed(count_up_to,second_count_up_to=100):lst=[iforiinrange(count_up_to)]lst2=[iforiinrange(second_count_up_to)]Timer.run()Adding custom descriptive names to your functionsIf you want to see a different name other than the function name in the final report you can pass that to the decorator usingname=""argument.@timethis([10],name="A list comprehension that counts up to 10")deffunction_to_be_timed(count_up_to):lst=[iforiinrange(count_up_to)]Timer.run()name                                      | Execution timeA list comprehension that counts up to 10 | 0.5393135Changing the number of times the function is repeated.By default, like timeit, The function is repeated 1 million times,
but this can be changed by passing arepeat=toTimer.run()like this.Timer.run(repeat=100)#The function to be timed will loop for hundred times.Comparing multiple functions.A common use case that I have found for the timeit module, is to compare
the runtime speed of two different algorithms, this is very easy to do in p-timeit.@timethis(100,name="using a for loop")defmy_func(count_up_to):lst=[]foriinrange(count_up_to):lst.append(i)@timethis(100,name="using a List comprehension")defmy_func_2(count_up_to):lst=[iforiinrange(count_up_to)]Timer.run(compare=True)Outputrank | name                       | Execution time1    | using a List comprehension | 2.34607040000000032    | using a for loop           | 4.37266As you can see the list comprehension is faster than using a for loop.Note: you can compare as many functions as you like. Not just two.
Thecompare=Trueflag formats the output, And orders the results from The fastest functions to the slowest.
You can still run multiple functions withTimer.run().Here's an example without compare@timethis([10],name="using a for loop")defmy_func(count_up_to):lst=[]foriinrange(count_up_to):lst.append(i)@timethis([10],name="using a List comprehension")defmy_func_2(count_up_to):lst=[iforiinrange(count_up_to)]@timethis([10],name="using two lists")defmy_func_3(count_up_to):lst=[iforiinrange(count_up_to)]lst2=[iforiinrange(count_up_to)]Timer.run()outputname                       | Execution timeusing a for loop           | 0.7021932000000001using a List comprehension | 0.6186622999999999using two lists            | 1.0627897000000002Notice that the functions are ordered as they were defined
and not by execution time.