napari.utils.perf#

Performance Monitoring.

The perfmon module lets you instrument your code and visualize its run-time behavior and timings in Chrome’s Tracing GUI.

To enable perfmon define the env var NAPARI_PERFMON as follows:

NAPARI_PERFMON=1

Activates perfmon, trace using Debug -> Performance Trace menu.

NAPARI_PERFMON=/path/to/config.json

Configure perfmon using the config.json configuration. See the PerfmonConfig docs for the spec of the config file.

Chrome Tracing#

Chrome has a nice built-in performance tool called chrome://tracing. Chrome can record traces of web applications. But the format is well-documented and anyone can create the files and use the nice GUI. And other programs accept the format including: 1) https://www.speedscope.app/ which does flamegraphs (Chrome doesn’t). 2) Qt Creator’s performance tools.

Monkey Patching#

The best way to add perf_timers is using the perfmon config file. You can list which methods or functions you want to time, and a perf_timer will be monkey-patched into each callable on startup. The monkey patching is done only if perfmon is enabled.

Trace On Start#

Add a line to the config file like:

“trace_file_on_start”: “/Path/to/my/trace.json”

Perfmon will start tracing on startup. You must quit napari with the Quit command for napari to write trace file. See PerfmonConfig docs.

Manual Timing#

You can also manually add “perf_timer” context objects and “add_counter_event()” and “add_instant_event()” functions to your code. All three of these should be removed before merging the PR into main. While they have almost zero overhead when perfmon is disabled, it’s still better not to leave them in the code. Think of them as similar to debug prints.

Classes

PerfEvent

A performance related event: timer, counter, etc.

Functions

napari.utils.perf.add_counter_event(name: str, **kwargs: float) None[source]#

Add one counter event.

Parameters:
  • name (str) – The name of this event like “draw”.

  • **kwargs (float) – The individual counters for this event.

Notes

For example add_counter_event(“draw”, triangles=5, squares=10).

napari.utils.perf.add_instant_event(name: str, *, category: str | None = None, process_id: int | None = None, thread_id: int | None = None, **kwargs: float) None[source]#

Add one instant event.

Parameters:
  • name (str) – Add this event.

  • category (str | None) – Comma separated categories such as “render,update”.

  • process_id (int | None) – The process id that produced the event.

  • thread_id (int | None) – The thread id that produced the event.

  • **kwargs – Arguments to display in the Args section of the Chrome Tracing GUI.

napari.utils.perf.block_timer(name: str, category: str | None = None, print_time: bool = False, *, process_id: int | None = None, thread_id: int | None = None, phase: str = 'X', **kwargs: float) Generator[PerfEvent, None, None][source]#

Time a block of code.

block_timer can be used when perfmon is disabled. Use perf_timer instead if you want your timer to do nothing when perfmon is disabled.

Notes

Most of the time you should use the perfmon config file to monkey-patch perf_timer’s into methods and functions. Then you do not need to use block_timer or perf_timer context objects explicitly at all.

Parameters:
  • name (str) – The name of this timer.

  • category (str) – Comma separated categories such as “render,update”.

  • print_time (bool) – Print the duration of the timer when it finishes.

  • **kwargs (dict) – Additional keyword arguments for the “args” field of the event.

Examples

with block_timer("draw") as event:
    draw_stuff()
print(f"The timer took {event.duration_ms} milliseconds.")
napari.utils.perf.perf_timer(name: str, category: str | None = None, print_time: bool = False, *, process_id: int | None = None, thread_id: int | None = None, phase: str = 'X', **kwargs: float) Generator[None, None, None][source]#

Do nothing when perfmon is disabled.