Skip to main content

ptimeit

codecov

timeit, 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.

Installation

With pip.

$ pip install pretty-timeit

With poetry.

$ poetry add pretty-timeit

Usage.

A simple example.

from ptimeit import timethis, Timer

# although this is a decorator, your original function will not be modified.
@timethis() 
def function_to_be_timed():
    lst = [i for i in range(10)]

Timer.run() # Call this at the end of the file.

output

name                 | Execution time
function_to_be_timed | 0.5608107

Note: By default Timer.run() Prints the results to the console. If you want it to return a string, do this.

Timer.run(print_results=False) # returns a string

Mixing 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 of function(*args, **kwargs).

@timethis( [10], {"second_count_up_to":10} )
def function_to_be_timed(count_up_to, second_count_up_to=100):
    lst = [i for i in range(count_up_to)]
    lst2 = [i for i in range(second_count_up_to)]

Timer.run()

Adding custom descriptive names to your functions

If you want to see a different name other than the function name in the final report you can pass that to the decorator using name="" argument.

@timethis([10], name="A list comprehension that counts up to 10")
def function_to_be_timed(count_up_to):
    lst = [i for i in range(count_up_to)]
Timer.run()
name                                      | Execution time
A list comprehension that counts up to 10 | 0.5393135

Changing 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 a repeat= to Timer.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")
def my_func(count_up_to):
    lst=[]
    for i in range( count_up_to): 
        lst.append(i)

@timethis(100, name="using a List comprehension")
def my_func_2(count_up_to):
    lst = [i for i in range(count_up_to)]

Timer.run(compare=True)

Output

rank | name                       | Execution time
1    | using a List comprehension | 2.3460704000000003
2    | using a for loop           | 4.37266

As 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. The compare=True flag formats the output, And orders the results from The fastest functions to the slowest. You can still run multiple functions with Timer.run().

Here's an example without compare

@timethis([10], name="using a for loop")
def my_func(count_up_to):
    lst=[]
    for i in range( count_up_to): 
        lst.append(i)

@timethis([10], name="using a List comprehension")
def my_func_2(count_up_to):
    lst = [i for i in range(count_up_to)]

@timethis([10], name="using two lists")
def my_func_3(count_up_to):
    lst = [i for i in range(count_up_to)]
    lst2 = [i for i in range(count_up_to)]

Timer.run()

output

name                       | Execution time
using a for loop           | 0.7021932000000001
using a List comprehension | 0.6186622999999999
using two lists            | 1.0627897000000002

Notice that the functions are ordered as they were defined and not by execution time.

Metadata

Release files for pretty-timeit 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pretty-timeit 0.1.0
File Size Uploaded
pretty-timeit-0.1.0.tar.gz 6.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pretty-timeit 0.1.0
File Interpreter ABI Platform
pretty_timeit-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 13.5 kB

Release files / pretty-timeit-0.1.0.tar.gz

Download URL pretty-timeit-0.1.0.tar.gz
Size 6.3 kB
Tags Source
SHA-256 checksum
How to use checksums
7fb25fa357400b7c759c86925d2b3ed54466289c5703ee089796fa8e23c43621
BLAKE2b-256 checksum
How to use checksums
b285b360b36504dbc792c4fa5bc7fa2aef733be2a725b907037cd2db59c5875a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.1.6 CPython/3.8.9 Windows/10

Release files / pretty_timeit-0.1.0-py3-none-any.whl

Download URL pretty_timeit-0.1.0-py3-none-any.whl
Size 7.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
74e4ffbd0132c2cb44f85799657e3d39fcebbd6d03090880946008ced18c5c32
BLAKE2b-256 checksum
How to use checksums
c8b1b5212bc9ca5eae817886c84648dd9412cede0d9231c4a03066e3da4d647d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.1.6 CPython/3.8.9 Windows/10

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page