Measuring code performance with Python's timeit module

Einblick Content Team - April 28th, 2023

Timeit is a module in the Python standard library that provides various functions for measuring the execution times of small portions of code. It can be used to compare different methods or implementations of algorithms and help understand performance tradeoffs. In this post, we’ll go over the timeit module, its relevant functions, and a few examples. Check out the full code in the canvas below or read on to learn more.

Basic Syntax: timeit.timeit(stmt, number)

The main two arguments you need are a statement (stmt), as a string, to execute and the number of times to execute the statement.

import timeit

# Trivial example
timeit.timeit(stmt = "[x**2 for x in range(0,10)]", number = 100)

Output:

0.0004509619902819395

Then you can repeat the time test using the convenient repeat() function:

  • The repeat argument is how many times the iterations of the statement are repeated.
  • The number argument is passed to the timeit() function, to determine how many times to run the statement.
timeit.repeat(repeat = 10, number = 1000)

Output:

[2.3720087483525276e-05,
 2.3379921913146973e-05,
 2.3350119590759277e-05,
 2.3289816454052925e-05,
 2.327980473637581e-05,
 2.3269793018698692e-05,
 2.326001413166523e-05,
 2.327095717191696e-05,
 2.326001413166523e-05,
 2.3259781301021576e-05]

Example with setup: timeit.timeit(stmt, setup, number)

It's important to note that the timeit() function works like a silo, unless otherwise configured, so if you need to define a function, for example, you need to do so within the function, using the setup argument.

Just like with the stmt argument, you can save the code as a string. Multi-line strings are necessary for defining functions, for loops, etc.

# Write function as string
setup = """def fact_n(n):
   if n < 2:
       return 1
   else:
       return n * fact_n(n-1)
"""

# Write statement to be timed
stmt = """for x in range(0, 5):
    fact_n(x)"""

# Time statement
timeit.timeit(stmt = stmt, setup = setup, number = 1000)

Output:

0.002592656994238496

Example with import and setup

Another way of using setup, is by invoking __main__ through an import statement. This way, you can import any functions that you've defined in your environment.

# Create and test function
def fact_n(n):
   """This is a recursive, computationally expensive way to calculate a factorial"""
   if n < 2:
       return 1
   else:
       return n * fact_n(n-1)

print(fact_n(3))
print(fact_n(4))

# Time statement, importing function from __main__
timeit.timeit(stmt = stmt, setup = "from __main__ import fact_n", number = 1000)

Output:

6
24
0.001599042909219861

Example with globals: timeit.timeit(stmt, globals, n)

Lastly, if you want to have access to all global namespace, you can use the globals argument, and set it equal to globals().

# Create and test function
def fact_n(n):
   """This is a recursive, computationally expensive way to calculate a factorial"""
   if n < 2:
       return 1
   else:
       return n * fact_n(n-1)

print(fact_n(3))
print(fact_n(4))

# Time statement, passing globals() to execute in global namespace
timeit.timeit(stmt = stmt, globals = globals(), number = 1000)

Output:

6
24
0.0016628799494355917

Example with Timer instance: timeit.Timer(stmt, setup)

Lastly, you can create a Timer instance, and call the timeit() and repeat() functions on the Timer instance. In this case, the Timer instance only needs stmt and setup, and you only pass the number argument directly into the timeit() function.

# Write function as string
setup = """def fact_n(n):
   if n < 2:
       return 1
   else:
       return n * fact_n(n-1)
"""

# Write statement to be timed
stmt = """for x in range(0, 5):
    fact_n(x)"""

# Instantiate Timer object, time statement
t = timeit.Timer(stmt = stmt, setup = setup)
t.timeit(number = 1000)

Output:

0.001657320186495781

About

Einblick is an agile data science platform that provides data scientists with a collaborative workflow to swiftly explore data, build predictive models, and deploy data apps. Founded in 2020, Einblick was developed based on six years of research at MIT and Brown University. Einblick customers include Cisco, DARPA, Fuji, NetApp and USDA. Einblick is funded by Amplify Partners, Flybridge, Samsung Next, Dell Technologies Capital, and Intel Capital. For more information, please visit www.einblick.ai and follow us on LinkedIn and Twitter.

Start using Einblick

Pull all your data sources together, and build actionable insights on a single unified platform.

  • All connectors
  • Unlimited teammates
  • All operators