Skip to main content

logo exectimeit

Accurate Measurement of Small Execution Times

PyPI - Version PyPI - Python Version GitHub License GitHub Actions Workflow Status GitHub last commit

Measuring small execution times (especially for fast routines $< 100$ milliseconds) in Python can be extremely challenging. The traditional way of timing code is to take the difference of system times before and after a function execution. However, this is highly susceptible to two types of errors:

  1. Random error: Environmental noise (OS scheduling, CPU frequency scaling) causes variation. This can be reduced by averaging multiple measurements.
  2. Systematic error: The overhead of invoking the timing instructions themselves is added to the measured duration, which is difficult to filter out.

This library implements the mathematical model proposed by Carlos Moreno and Sebastian Fischmeister [1] to circumvent systematic measurement overhead.


The Mathematics Behind It

Instead of measuring a single execution of a function $f$, we measure the total duration of executing the function sequentially $k$ times inside a single timing block, for $k = 1, 2, \dots, n$ (where $n$ is the number of repetitions, recommended $\ge 3$).

The total measured time $T_k$ for $k$ executions is modeled as a linear function: $$T_k = k \cdot t_{\text{exec}} + t_{\text{overhead}} + \epsilon_k$$

Where:

  • $t_{\text{exec}}$ is the actual, true execution time of a single run.
  • $t_{\text{overhead}}$ is the fixed overhead of starting/stopping the timer.
  • $\epsilon_k$ is the random measurement error for trial $k$.

By fitting a simple linear regression $y = m \cdot x + b$ to the data points $(k, T_k)$:

  • The slope ($m$) represents the true single-run execution time ($t_{\text{exec}}$), entirely free of the timer's start/stop overhead.
  • The intercept ($b$) represents the fixed timer overhead ($t_{\text{overhead}}$).
  • The Residual Standard Error (RSE) provides a precise measure of the variation or noise: $$rse = \sqrt{\frac{\sum (y_i - \hat{y}_i)^2}{n - 2}}$$
Linear Fit Representation

To eliminate loop iteration overhead in Python, exectimeit dynamically compiles and caches unrolled execution routines for each $k$.


Installation

pip install exectimeit

Or install from GitHub:

pip install git+https://github.com/mariolpantunes/exectimeit.git@main

Usage

Option 1: Direct function call wrapper

You can measure any callable using the timeit function. It returns an ExecTimeResult named tuple containing:

  • time: estimated execution time per run (in seconds)
  • rse: residual standard error of the linear fit (in seconds)
  • value: the return value of the function
from exectimeit import timeit
import time

def my_fast_function(x, y):
    time.sleep(0.001)  # Simulating some work
    return x + y

# Measure with n=5 repetitions
result = timeit(5, my_fast_function, 2, y=3)

# You can access properties by name:
print(f"Time: {result.time:.6f}s, RSE: {result.rse:.6f}s, Return value: {result.value}")

# Or unpack like a standard tuple:
t, rse, val = result

Option 2: Decorator

You can decorate your functions with @exectime to automatically wrap them. When called, the decorated function will return the ExecTimeResult.

from exectimeit import exectime

@exectime(n=5)
def my_decorated_function(a):
    return a * a

# Executing the function returns the measurement named tuple:
t, rse, val = my_decorated_function(10)
print(f"Time: {t:.6f}s, Return value: {val}")

Running Unit Tests

The test suite validates both deterministic mock-timing regression math and real-time execution. Run them with:

python3 -m unittest discover -s test

Documentation

Detailed package documentation is hosted on GitHub Pages: https://mariolpantunes.github.io/exectimeit/

To generate the docs locally:

pip install pdoc
PYTHONPATH=src pdoc --math -d google -o docs exectimeit \
  --logo "assets/logo.svg" \
  --favicon "assets/logo.svg"

References

[1] C. Moreno and S. Fischmeister, "Accurate Measurement of Small Execution Times—Getting Around Measurement Errors," in IEEE Embedded Systems Letters, vol. 9, no. 1, pp. 17-20, March 2017, doi: 10.1109/LES.2017.2654160.


Authors


License

This project is licensed under the MIT License - see the LICENSE file for details.

Metadata

Release files for exectimeit 0.2.1

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

Source distribution (sdist)

Source distribution for exectimeit 0.2.1
File Size Uploaded Provenance
exectimeit-0.2.1.tar.gz 8.5 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for exectimeit 0.2.1
File Interpreter ABI Platform
exectimeit-0.2.1-py3-none-any.whl Python 3 none any Details

Total release size: 16.1 kB

Release files / exectimeit-0.2.1.tar.gz

Download URL exectimeit-0.2.1.tar.gz
Size 8.5 kB
Tags Source
SHA-256 checksum
How to use checksums
4fb5eb497f5b700c5bec744e6f4c4a19507b592d701d601d290c2afa3d43328e
BLAKE2b-256 checksum
How to use checksums
a08ba6877f93668efc9fb450bb8c270e1291253f63e5c19cdb2161d396858977
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.12

Release files / exectimeit-0.2.1-py3-none-any.whl

Download URL exectimeit-0.2.1-py3-none-any.whl
Size 7.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ff4e5d42c834d960ca9fe5eaeab711afd03a6b5596ad5bbd623a0777d6601cbe
BLAKE2b-256 checksum
How to use checksums
cc13fb3a0a54e5767c47be2ffb118daaefd043764c5b87ccc33eb7c011c15a7a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.12

Security for exectimeit 0.2.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

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