# OpenMed Profiling Tools for Performance Debugging: A Complete Guide

> Debug medical NLP pipelines with OpenMed profiling tools. Discover the Profiler class, decorators, and timers for detailed execution timings and bottleneck identification.

- Repository: [Maziyar Panahi/openmed](https://github.com/maziyarpanahi/openmed)
- Tags: how-to-guide
- Published: 2026-06-10

---

**OpenMed ships with a built-in `openmed.utils.profiling` module that provides four complementary utilities—the `Profiler` class, global helper functions, a `@profile` decorator, and lightweight `Timer` tools—to capture detailed execution timings for debugging bottlenecks in medical NLP pipelines.**

The `maziyarpanahi/openmed` repository includes a native performance debugging suite designed specifically for healthcare AI workflows. These OpenMed profiling tools enable developers to measure model loading latency, track inference durations, and identify preprocessing slowdowns without requiring external dependencies. All functionality resides in a single, lightweight module that integrates seamlessly into existing Python codebases.

## The `openmed.utils.profiling` Module Architecture

The profiling suite is implemented in [`openmed/utils/profiling.py`](https://github.com/maziyarpanahi/openmed/blob/main/openmed/utils/profiling.py), which defines the core `Profiler` class, timing data structures, and global state management. According to the OpenMed source code, the module uses a singleton pattern for global profiling sessions while supporting isolated local profiler instances for targeted debugging of specific pipeline components.

## Core OpenMed Profiling Components

### The `Profiler` Class for Scoped Measurements

The `Profiler` class acts as a context-manager-based recorder that accumulates `TimingResult` objects. In [`openmed/utils/profiling.py`](https://github.com/maziyarpanahi/openmed/blob/main/openmed/utils/profiling.py) (lines 22-33), the class definition includes an `enabled` flag and metadata storage capabilities. The `measure()` method (lines 60-78) creates scoped timers, while `report()` (lines 15-30) returns a `ProfileReport` containing all captured timings and statistical breakdowns.

### Global Helper Functions

OpenMed provides singleton-based global helpers to enable application-wide profiling without passing instances between functions. The `enable_profiling()` function (lines 45-52) initializes and starts a global profiler, `disable_profiling()` (lines 53-58) stops the current session, and `get_profile_report()` (lines 60-63) retrieves the accumulated timing data. These utilities allow seamless integration into existing pipeline code without refactoring function signatures.

### The `@profile` Decorator

For automatic function-level timing, the `@profile` decorator (implemented in lines 65-88 of [`profiling.py`](https://github.com/maziyarpanahi/openmed/blob/main/profiling.py)) wraps any callable to record its execution duration using the global profiler instance. This approach eliminates the need for explicit `with` blocks when timing specific functions repeatedly across your medical NLP workflow.

### Lightweight `Timer` and `timed` Utilities

The `Timer` class and `timed` context manager provide ad-hoc measurement capabilities primarily intended for logging and rapid debugging. `Timer.start()` and `Timer.stop()` return elapsed milliseconds, while the `timed()` context manager (lines 55-74) yields a `Timer` instance and automatically logs results on exit, making it ideal for quick diagnostic statements during development.

## Practical Examples for OpenMed Performance Debugging

### Manual Profiling with Local `Profiler` Instances

Use the `Profiler` class directly when you need isolated timing sessions for specific pipeline sections:

```python
from openmed.utils.profiling import Profiler

profiler = Profiler(enabled=True)
with profiler.measure("load_model"):
    model = load_my_model()          # <- your costly operation

with profiler.measure("inference"):
    result = model.predict(text)

print(profiler.report().format_report())

```

### Global Profiling Sessions

Enable application-wide debugging to capture timings across multiple modules:

```python
from openmed.utils.profiling import enable_profiling, get_profile_report

enable_profiling()                     # starts a global session

# … run any code that calls `profile()` or `Profiler.measure()` …

report = get_profile_report()
print(report.format_report(include_metadata=True))

```

### Automatic Function Timing with Decorators

Apply the `@profile` decorator to capture timings without modifying function internals:

```python
from openmed.utils.profiling import profile

@profile("tokenize")
def tokenize(text):
    return tokenizer.encode(text)

# each call is timed automatically

tokens = tokenize("Hello world")

```

### Quick Timing with `timed` Context Managers

Use `timed()` for lightweight, logging-friendly measurements:

```python
from openmed.utils.profiling import timed

with timed("model inference"):
    output = model.predict(batch)

# Logs something like: "model inference took 123.45ms"

```

## Report Generation and Output Formats

All OpenMed profiling tools produce human-readable reports via `ProfileReport.format_report()` or `BatchMetrics.format_report()`. These methods output total duration, per-operation breakdowns, and optional metadata, enabling quick identification of bottlenecks in medical model inference workflows.

## Testing and Validation

The intended usage patterns and API behaviors are verified in [`tests/unit/test_profiling.py`](https://github.com/maziyarpanahi/openmed/blob/main/tests/unit/test_profiling.py), which contains comprehensive unit tests for the `Profiler` class, global helper functions, `@profile` decorator, and `Timer` utilities. Developers should reference these tests to understand proper initialization sequences and edge cases for the global profiler singleton.

## Summary

- **Scoped Profiling**: Use the `Profiler` class with `measure()` context managers for targeted timing of specific code blocks in [`openmed/utils/profiling.py`](https://github.com/maziyarpanahi/openmed/blob/main/openmed/utils/profiling.py).
- **Global Sessions**: Enable application-wide debugging with `enable_profiling()` and retrieve results via `get_profile_report()` without modifying function signatures throughout your codebase.
- **Automatic Decoration**: Apply the `@profile` decorator to capture function-level timings transparently using the global profiler instance.
- **Ad-hoc Timing**: Leverage `Timer` and `timed()` for lightweight, logging-friendly measurements during rapid debugging cycles.
- **Unified Reporting**: All tools generate structured reports through `ProfileReport.format_report()`, providing consistent visibility into model loading and inference performance.

## Frequently Asked Questions

### How do I enable profiling globally in an OpenMed application?

Call `enable_profiling()` at the start of your application to initialize the global profiler singleton in [`openmed/utils/profiling.py`](https://github.com/maziyarpanahi/openmed/blob/main/openmed/utils/profiling.py). This captures timings from any `@profile` decorators or explicit `Profiler.measure()` calls throughout your codebase. Retrieve the final report using `get_profile_report()` after your pipeline completes execution.

### What is the difference between the `Profiler` class and the `Timer` utility?

The `Profiler` class accumulates multiple `TimingResult` objects into a comprehensive `ProfileReport`, making it suitable for benchmarking complete pipelines and comparing multiple operations. The `Timer` class provides single-shot measurements primarily for logging purposes, while the `timed()` context manager automatically logs elapsed time without accumulating results into a structured report.

### Can I use the `@profile` decorator when the global profiler is disabled?

Yes, the decorator safely handles disabled states without raising errors. However, it will only record timing data when the global profiler is enabled via `enable_profiling()`. You do not need to remove the decorator when profiling is turned off—simply ensure `enable_profiling()` is called before the decorated functions execute to capture measurements.

### Where are the profiling utilities tested in the OpenMed repository?

All profiling functionality is validated in [`tests/unit/test_profiling.py`](https://github.com/maziyarpanahi/openmed/blob/main/tests/unit/test_profiling.py), which contains unit tests demonstrating the intended usage patterns for the `Profiler` class, global helper functions, `@profile` decorator, and `Timer` utilities. These tests verify that `ProfileReport` objects correctly aggregate timing results and that the global singleton behaves as expected across multiple import contexts.