Skip to content

Conversation

@cvanelteren
Copy link
Collaborator

@cvanelteren cvanelteren commented Dec 30, 2025

This PR rewires ultraplot’s import path to lazy‑load modules/registries and defer setup/registration work until first access, moves docstring snippet setup into ultraplot.internals.docstring with lazy snippet resolution, and defers optional dependency imports (IPython/pyplot/cartopy/basemap) while preserving the public API.

Import time report (python -X importtime -c "import ultraplot", Python 3.13.11):

  • Logs: import_before_lazy.log, import_after_lazy.log
  • Total before: 838.4 ms
  • Total after: 12.2 ms
  • Delta: -826.2 ms (~98.5% reduction)

Top ultraplot modules (before):

  838.4 ms | 49.4 ms | ultraplot
  408.8 ms |  0.6 ms | ultraplot.internals
  289.4 ms |  7.7 ms | ultraplot.config
  209.5 ms |  0.4 ms | ultraplot.internals.docstring
   51.3 ms |  0.6 ms | ultraplot.axes
   29.9 ms | 14.6 ms | ultraplot.axes.cartesian
   15.0 ms | 14.8 ms | ultraplot.axes.plot
    8.6 ms |  6.2 ms | ultraplot.axes.base
    6.7 ms |  6.5 ms | ultraplot.axes.geo
    5.8 ms |  5.8 ms | ultraplot.scale
    3.7 ms |  3.7 ms | ultraplot.figure
    3.4 ms |  3.4 ms | ultraplot.axes.polar

Top external modules (before):

  281.7 ms |  0.3 ms | IPython
  211.0 ms |  2.1 ms | IPython.terminal.embed
  158.4 ms |  0.3 ms | matplotlib.axes
  126.9 ms |  2.3 ms | IPython.terminal.interactiveshell
  118.3 ms |  5.2 ms | matplotlib.axes._base
  114.9 ms |  7.4 ms | matplotlib
   95.1 ms |  6.5 ms | matplotlib.offsetbox
   69.8 ms |  1.1 ms | IPython.core.application
   64.4 ms |  0.7 ms | IPython.terminal.debugger
   60.5 ms |  1.6 ms | numpy
   60.5 ms |  1.0 ms | matplotlib.rcsetup
   58.9 ms |  4.8 ms | IPython.core.completer

Top ultraplot modules (after):

   12.2 ms | 0.2 ms | ultraplot
    0.2 ms | 0.2 ms | ultraplot._version

Top external modules (after):

    8.2 ms | 1.1 ms | ast
    5.7 ms | 0.5 ms | re
    5.3 ms | 1.6 ms | site
    3.6 ms | 1.2 ms | enum
    3.5 ms | 0.2 ms | pathlib
    2.5 ms | 0.5 ms | functools
    1.9 ms | 1.0 ms | collections
    1.8 ms | 0.6 ms | pathlib._local
    1.6 ms | 0.4 ms | os
    1.4 ms | 0.5 ms | pathlib._abc
    1.4 ms | 0.3 ms | re._compiler
    1.3 ms | 0.5 ms | encodings

Closes #395

@cvanelteren
Copy link
Collaborator Author

cvanelteren commented Dec 30, 2025

This change set reworks ultraplot’s import path to be lazy by default: ultraplot/__init__.py no longer star‑imports everything up front, instead mapping attributes to their modules via __all__ and deferring setup/registration until first access, while still exposing registry classes and optional dependencies (pyplot, cartopy, basemap, and legend) on demand and guarding pytest_plugins. Internals now avoid eager submodule imports and only pull in rcsetup or matplotlib rcParams when needed, and the warnings alias was reverted back to the canonical warnings name. Docstring snippet setup was moved into ultraplot.internals.docstring with a lazy resolver to import modules that register missing snippets, and matplotlib imports inside _concatenate_inherited are delayed. config_inline_backend now imports IPython lazily. Net effect: import time drops from ~838 ms to ~12 ms on my machine while keeping API behavior intact; targeted tests pass, and the full suite progressed without failures before timeout.

@codecov
Copy link

codecov bot commented Dec 30, 2025

@cvanelteren cvanelteren requested a review from beckermr December 30, 2025 07:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fix high import time

1 participant