Skip to main content

Tiny dependency-free timing decorator, context manager, and stopwatch utility.

Project description

timerx

Version Python License: MIT Tests Dependencies

timerx is a tiny, dependency-free timing utility for Python. It gives you one simple API for timing functions, code blocks, and named stopwatches, then keeps cumulative stats so you can inspect timings programmatically or print a compact summary.

Use it when you want quick timing information without setting up a profiler or manually calling time.perf_counter() throughout your code.

Features

  • Works as a decorator, context manager, or manual stopwatch
  • Supports sync and async functions
  • Accumulates count, total, average, min, max, and last duration
  • Records timings even when decorated functions or context blocks raise
  • Supports concurrent named stopwatches
  • Provides isolated TimerX() instances for libraries and tests
  • Uses only the Python standard library at runtime

Install

pip install timerx

For local development:

pip install -e ".[test]"
pytest

Quick Example

This example shows the three main ways to use timerx: decorate a function, measure a block, and manually start and stop a named timer.

import time
import timerx


@timerx.track
def train_model():
    time.sleep(0.2)


train_model()
train_model()

with timerx.lap("preprocessing"):
    time.sleep(0.05)

timerx.start("postprocess")
time.sleep(0.01)
elapsed = timerx.stop("postprocess")

print(f"postprocess took {elapsed:.4f}s")
print(timerx.summary())

Example summary:

name           count  total     avg       min       max       last
-------------  -----  --------  --------  --------  --------  --------
train_model    2      400ms     200ms     200ms     200ms     200ms
preprocessing  1      50ms      50ms      50ms      50ms      50ms
postprocess    1      10ms      10ms      10ms      10ms      10ms

Timing Functions

Use @timerx.track when you want to measure every call to a function. It works with or without parentheses. By default, the function name is used as the timing label, but you can provide a custom name.

@timerx.track
def load_data():
    return [1, 2, 3]


@timerx.track()
def preprocess():
    return "ready"


@timerx.track(name="model.fit")
def train():
    return "done"

Stats accumulate across multiple calls:

load_data()
load_data()

stats = timerx.get_stats()
print(stats["load_data"]["count"])  # 2
print(stats["load_data"]["avg"])    # average duration in seconds

Decorated functions are recorded even if they raise an exception, and the original exception is still raised normally.

Timing Async Functions

track also supports coroutine functions.

@timerx.track(name="fetch")
async def fetch_rows():
    return await client.get("/rows")

Timing Code Blocks

Use timerx.lap(name) as a context manager when you want to measure part of a function. Laps record timings even when the block raises, and nested laps work naturally.

with timerx.lap("pipeline"):
    with timerx.lap("load"):
        rows = load_rows()

    with timerx.lap("transform"):
        rows = transform(rows)

Stopwatches

Use start(name) and stop(name) when the start and end of the work are in different places. Named stopwatches can run concurrently. If you start the same name more than once, timerx treats it as a stack, so stop(name) closes the most recent start.

timerx.start("download")
timerx.start("parse")

timerx.stop("parse")
timerx.stop("download")

stop(name) returns the elapsed duration in seconds and also records it in the same stats store used by decorators and laps.

Reading Results

Use summary() for human-readable output:

print(timerx.summary())
print(timerx.summary(unit="ms"))
print(timerx.summary(sort_by="total"))  # most expensive first

Supported units are auto, s, ms, us, µs, and microseconds. Auto mode picks seconds, milliseconds, or microseconds per value.

Pass sort_by with any stat column name (count, total, avg, min, max, last) to sort rows descending by that column. Default is insertion order.

Use get_stats() when you need data for tests, logs, dashboards, or your own formatting:

stats = timerx.get_stats()

{
    "preprocessing": {
        "count": 1,
        "total": 0.00512,
        "min": 0.00512,
        "max": 0.00512,
        "last": 0.00512,
        "avg": 0.00512,
    }
}

Durations in get_stats() are always stored as seconds.

Isolated Instances

The top-level timerx.track, timerx.lap, timerx.start, and timerx.stop helpers share one global timer. For libraries, tests, or applications that need separate timing state, create a TimerX() instance.

from timerx import TimerX

tx = TimerX()

with tx.lap("local"):
    run_work()

print(tx.get_stats())

Resetting

Use reset() to clear recorded timings and running stopwatches.

timerx.reset()

Development

pip install -e ".[test]"
pytest
python examples/demo.py

Contributing

Contributions are welcome. If you find a bug, have an API idea, or want to add coverage for an edge case, please open an issue or pull request.

License

timerx is released under the MIT License. See LICENSE for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

timerx-0.3.0.tar.gz (16.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

timerx-0.3.0-py3-none-any.whl (7.1 kB view details)

Uploaded Python 3

File details

Details for the file timerx-0.3.0.tar.gz.

File metadata

  • Download URL: timerx-0.3.0.tar.gz
  • Upload date:
  • Size: 16.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for timerx-0.3.0.tar.gz
Algorithm Hash digest
SHA256 c00fbf8254907c842222386c156abe5f1662e0f9089770793b4affee20a7db71
MD5 a210efb605c87ce8d190f83f015fd428
BLAKE2b-256 377f66d67fb9a743d2a01bdccdd0d878964f90a676961a57f1581a4f87f72928

See more details on using hashes here.

Provenance

The following attestation bundles were made for timerx-0.3.0.tar.gz:

Publisher: publish.yml on abhijatchaturvedi/timerx

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file timerx-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: timerx-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 7.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for timerx-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b981be90df71f4141154f12852ce60c6495f524e9bcc72abc2dab9f82ff40c92
MD5 32ebace05ef88e22680b7f897da530e8
BLAKE2b-256 1be0aa39fe304b96c02dbdfd45df77a5f15d4d8c780ae3bf7b32ac15bf788a49

See more details on using hashes here.

Provenance

The following attestation bundles were made for timerx-0.3.0-py3-none-any.whl:

Publisher: publish.yml on abhijatchaturvedi/timerx

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page