Time a block of code.
Project description
A function-decorator and a context-manager (with-statement) to time a block of code.
If your program is executing a lengthy operation, it’s good UI to let the user know what’s going on, rather than just silently chomping along. The user will have insight on what the process is stuck on and can decide if that was expected or not. This library lets the programmer tag some functions with a decorator or with-statement that logs when the function starts and finishes executing.
The user won’t want to see every function, but judiciously labeling a few top-level blocks with human-readable strings makes the program’s running times more understandable.
Logging the start and end can also be useful for high-level macro-optimization. line_profiler will measure every line, which comes with overhead and lots more data. Most lines are not the bottleneck, so this is just adding hay to the haystack and the performance overhead. line_profiler is good for micro-optimization when you already know where the bottleneck is; this package is good for learning what high-level operation is the bottleneck.
Quickstart
$ pip install charmonium.time_block
>>> import charmonium.time_block as ch_time_block
>>> import time
>>>
>>> def main():
... with ch_time_block.ctx("downloading data"):
... time.sleep(0.2)
...
>>> main()
downloading data: running
downloading data: finished in now
Equivalent a decorator:
>>> @ch_time_block.decor()
... def download_data():
... time.sleep(0.2)
...
>>> download_data()
download_data: running
download_data: finished in now
Like function profiling, but unlike other block-loggers, this package maintains a call stack of declared blocks (not every function). This “perforated stack” lets the programmer explicitly what gets logged to the user. In particular, the description field allows one to customize the representation of that stack frame, and the comment field allows one to add a message just at the start, such as the problem-size.
>>> @ch_time_block.decor(
... # fn params are available for use in the format string
... description="delete-{x}",
... comment="({x} nodes)",
... )
... def delete_nodes(x):
... with ch_time_block.ctx(
... description=f"finder-{x}",
... comment=f"({x} nodes)",
... ):
... time.sleep(0.1)
...
>>> delete_nodes(32)
delete-32: running
delete-32 > finder-32: running
delete-32 > finder-32: finished in now
delete-32: finished in now
Unlike external profiling, this package reports in realtime to logger (destination customizable). This is intended to let the user know what the code is doing right now.
Since this plugs into Python’s logger infrastructure, this can feed a pipeline that checks the application health.
This records process’s increase in memory usage (relatively cross-platform method using psutil) when do_gc=True, which gives a rough estimate of the memory leaked by the block. If a function consistently uses memory that doesn’t get freed when the function returns, it may indicate a memory leak. In high-level graph processing code, this is helpful to know _which_ transformation is eating up all of RAM.
>>> variable = []
>>> @ch_time_block.decor()
... def main():
... # Oops, leaking memory in global variable
... variable.append("abc" * 16384)
...
>>> main()
main: running
main: finished in now, leaked ...KiB
TODO
Explain iter, iter no elements, and async variants
Describe workflow
Note on performance/coarseness
Have global disable
Have context disable?
Documentation explains two ways of getting the stats: event-based and batch
Print, structlog, logging, rich backends
Should be very easy to get a print; then ensure doctests work.
Integration with other profilers
There should be an easy integration with Typer/Click and with global/atexit
Persistence
Save at final frame
Use hash of frame func + module version + global version
Frames have optional data
Could have size vector
Could implement global progress bar
Show the active awaitables?
Can we do async_ctx? Probably not. If not, explain why in README
Should we be an async event loop? Probably not.
Use term scope timer in documentation
Differentiators: print, time async, time iters, includes memory
Similar projects:
cProfile
line_profiler
memory-profiler
Plug in to existing profile visualizers. Make a flame graph.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file charmonium_time_block-1.0.0.tar.gz.
File metadata
- Download URL: charmonium_time_block-1.0.0.tar.gz
- Upload date:
- Size: 13.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.4.1 CPython/3.13.13 Linux/6.18.33
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
54e48376601a4247637f6d74d84d94484432efaa0b90ba68b9882afbed4f67af
|
|
| MD5 |
274c00f204bc74b4c39225938d1fc9a8
|
|
| BLAKE2b-256 |
443b32c7816259377df85bf330e552411556af734b50168797bd5a544b669616
|
File details
Details for the file charmonium_time_block-1.0.0-py3-none-any.whl.
File metadata
- Download URL: charmonium_time_block-1.0.0-py3-none-any.whl
- Upload date:
- Size: 14.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.4.1 CPython/3.13.13 Linux/6.18.33
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
47544ebfc934ea4558fa7c51e056b745b44d31297f2eaf41add787c7452ab092
|
|
| MD5 |
8536e325422cd57477116432f6e09875
|
|
| BLAKE2b-256 |
57cc2a2274720f9b4af8f12e37bbda79fe109bf2096b2aa6409dd3f75aaf4d91
|