Skip to main content

BisTiming

https://github.com/ianlini/bistiming/actions/workflows/main.yml/badge.svg https://readthedocs.org/projects/pip/badge/ https://img.shields.io/pypi/v/bistiming.svg https://img.shields.io/pypi/l/bistiming.svg https://img.shields.io/github/stars/ianlini/bistiming.svg?style=social

A logging-friendly stopwatch and profiling tool for Python.

When we search the stopwatch or timing module for Python on the internet, we can find a lot of code snippets, but none of them is powerful or convenient enough to do our daily jobs. BisTiming aims at implementing all the missing functions in those code snippets and prevents us from reinventing the wheel. It is very useful when we want to log something with some timing information or optimize the performance of our code.

This package is tested with Python 3.8 to 3.14, but might also work in other Python versions.

Installation

pip install bistiming

Getting Started

BisTiming has a context manager interface that logs the running time of a code block easily, and it also offers a low-level API to help time multiple segments or loops of code easily.

See examples for all the useful examples.

Context Manager

The simplest way to use BisTiming is by using the context manager Stopwatch and include the code we want to evaluate:

>>> from bistiming import Stopwatch
>>> from time import sleep
>>> with Stopwatch("Waiting"):
...     print("do something")
...     sleep(0.1)
...     print("finished something")
...
...Waiting
do something
finished something
...Waiting done in 0:00:00.100330

We can use the parameter logger and logging_level to tell the stopwatch to output using a logger:

>>> import logging
>>> logging.basicConfig(
...     level=logging.DEBUG,
...     format="[%(asctime)s] %(levelname)s: %(name)s: %(message)s")
>>> logger = logging.getLogger(__name__)
>>> with Stopwatch("Waiting", logger=logger, logging_level=logging.DEBUG):
...     print("do something")
...     sleep(0.1)
...     print("finished something")
...
[2019-04-24 22:27:52,347] DEBUG: __main__: ...Waiting
do something
finished something
[2019-04-24 22:27:52,448] DEBUG: __main__: ...Waiting done in 0:00:00.100344

Another common use case is to evaluate the running time of a specific code segment in a loop, we can initialize the stopwatch outside the loop, and reuse it in the loop:

>>> timer = Stopwatch("Waiting")
>>> for i in range(2):
...     with timer:
...         print("do something 1")
...         sleep(0.1)
...         print("finished something 1")
...     print("do something 2")
...     sleep(0.1)
...     print("finished something 2")
...
...Waiting
do something 1
finished something 1
...Waiting done in 0:00:00.100468
do something 2
finished something 2
...Waiting
do something 1
finished something 1
...Waiting done in 0:00:00.100440
do something 2
finished something 2
>>> timer.split_elapsed_time
[datetime.timedelta(microseconds=100468),
 datetime.timedelta(microseconds=100440)]
>>> timer.get_cumulative_elapsed_time()
datetime.timedelta(microseconds=200908)

Each item in split_elapsed_time is the running time of the code segment in each iteration, and we can use get_cumulative_elapsed_time() to get the total running time of the code segment.

Low-level API

The low-level API is similar to a stopwatch in real life. A simple use case using the low-level API is:

>>> from time import sleep
>>> from bistiming import Stopwatch
>>> timer = Stopwatch("Waiting").start()
...Waiting
>>> sleep(0.2)  # do the first step of my program
>>> timer.split()
...Waiting done in 0:00:00.201457
>>> sleep(0.1)  # do the second step of my program
>>> timer.split()
...Waiting done in 0:00:00.100982

The context manager

>>> with Stopwatch("Waiting"):
...     sleep(0.1)
...Waiting
...Waiting done in 0:00:00.100330

is actually equivalent to the low-level API:

>>> timer = Stopwatch("Waiting").start()
...Waiting
>>> sleep(0.1)
>>> timer.pause()
>>> timer.split()
...Waiting done in 0:00:00.100330

Advance Profiling

MultiStopwatch in this package contains multiple Stopwatch, so we can use them to define each code segment we want to evaluate and compare easily:

>>> from time import sleep
>>> from bistiming import MultiStopwatch
>>> timers = MultiStopwatch(2, verbose=False)
>>> for i in range(5):
...    for i in range(2):
...       with timers[0]:
...             sleep(0.1)
...    with timers[1]:
...       sleep(0.1)
...
>>> print(timers.format_statistics())
╒═══════════════════════════╤══════════════╤════════════╤══════════════════╕
│ cumulative_elapsed_time   │   percentage │   n_splits │ mean_per_split   │
╞═══════════════════════════╪══════════════╪════════════╪══════════════════╡
│ 0:00:01.002417            │     0.666377 │         10 │ 0:00:00.100242   │
├───────────────────────────┼──────────────┼────────────┼──────────────────┤
│ 0:00:00.501861            │     0.333623 │          5 │ 0:00:00.100372   │
╘═══════════════════════════╧══════════════╧════════════╧══════════════════╛

Documentation

There are a lot more ways to use this package. See the documentation for more information.

Metadata

Release files for bistiming 0.5.1.post0

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

Source distribution (sdist)

Source distribution for bistiming 0.5.1.post0
File Size Uploaded
bistiming-0.5.1.post0.tar.gz 9.4 kB Details

Built distribution (wheel)

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

Total release size: 19.3 kB

Release files / bistiming-0.5.1.post0.tar.gz

Download URL bistiming-0.5.1.post0.tar.gz
Size 9.4 kB
Tags Source
SHA-256 checksum
How to use checksums
252b404c2d3f128048338563174834206b94479c1d1612c069372e4473adc53b
BLAKE2b-256 checksum
How to use checksums
15a501849d5880492c7ffc7ed4bf0420fc83223e1a8c1f588683cb860740244e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.8.4 CPython/3.13.0 Linux/6.8.0-1016-azure

Release files / bistiming-0.5.1.post0-py3-none-any.whl

Download URL bistiming-0.5.1.post0-py3-none-any.whl
Size 9.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
27629c488613829ef4ddf08b717dbe1a6c4fb617b6aa54bb5fc4016f1ded8307
BLAKE2b-256 checksum
How to use checksums
02eb0ee84f07112c3f460751b9def3824977e4bbf1485eb38fbedc7222151be5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.8.4 CPython/3.13.0 Linux/6.8.0-1016-azure

Release history Release notifications | RSS feed

This release

0.5.1.post0 This release

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.1

2 release files

0.1.0

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