From 0c0c6e595e4bcb28451873e819cdb58d15448721 Mon Sep 17 00:00:00 2001 From: David Manthey Date: Wed, 9 Feb 2022 08:24:48 -0500 Subject: [PATCH] Reduce import time by lazily importing slow modules. --- CHANGELOG.md | 2 +- .../large_image_source_bioformats/__init__.py | 16 +++++++++--- .../nd2/large_image_source_nd2/__init__.py | 26 +++++++++++++------ 3 files changed, 32 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f08bc53cd..71ee58d1d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,7 @@ - Improve TileSource class repr ([#765](../../pull/765)) - Improve frame slider response with base quads ([#771](../../pull/771)) - Default to nearest-neighbor scaling in lossless image conversion ([#772](../../pull/772)) -- Improve the import time ([#775](../../pull/775)) +- Improve the import time ([#775](../../pull/775), [#777](../../pull/777)) ### Bug Fixes - The tile iterator could return excess tiles with overlap ([#773](../../pull/773)) diff --git a/sources/bioformats/large_image_source_bioformats/__init__.py b/sources/bioformats/large_image_source_bioformats/__init__.py index 915a77356..7db64148f 100644 --- a/sources/bioformats/large_image_source_bioformats/__init__.py +++ b/sources/bioformats/large_image_source_bioformats/__init__.py @@ -28,8 +28,6 @@ import threading import types -import bioformats -import javabridge import numpy from pkg_resources import DistributionNotFound, get_distribution @@ -46,6 +44,9 @@ # package is not installed pass +bioformats = None +# import javabridge +javabridge = None _javabridgeStarted = None _openImages = [] @@ -100,6 +101,14 @@ def _startJavabridge(logger): global _javabridgeStarted if _javabridgeStarted is None: + # Only import these when first asked. They are slow to import. + global bioformats + global javabridge + if bioformats is None: + import bioformats + if javabridge is None: + import javabridge + # We need something to wake up at exit and shut things down monitor = threading.Thread(target=_monitor_thread) monitor.daemon = True @@ -119,7 +128,8 @@ def _startJavabridge(logger): def _stopJavabridge(*args, **kwargs): global _javabridgeStarted - javabridge.kill_vm() + if javabridge is not None: + javabridge.kill_vm() _javabridgeStarted = None diff --git a/sources/nd2/large_image_source_nd2/__init__.py b/sources/nd2/large_image_source_nd2/__init__.py index 3c6241fbb..7331c9b49 100644 --- a/sources/nd2/large_image_source_nd2/__init__.py +++ b/sources/nd2/large_image_source_nd2/__init__.py @@ -21,14 +21,7 @@ import types import warnings -# Work around an issue in the PIMS package (can be removed once pims is -# released for Python 3.10). This must be before improt nd2reader. -if True: - import collections.abc - collections.Iterable = collections.abc.Iterable - import cachetools -import nd2reader import numpy from pkg_resources import DistributionNotFound, get_distribution @@ -37,6 +30,8 @@ from large_image.exceptions import TileSourceError, TileSourceFileNotFoundError from large_image.tilesource import FileTileSource +nd2reader = None + try: __version__ = get_distribution(__name__).version except DistributionNotFound: @@ -44,7 +39,21 @@ pass -warnings.filterwarnings('ignore', category=UserWarning, module='nd2reader') +def _lazyImport(): + """ + Import the nd2reader module. This is done when needed rather than in the + module initialization because it is slow. + """ + global nd2reader + + if nd2reader is None: + # Work around an issue in the PIMS package (can be removed once pims is + # released for Python 3.10). This must be before import nd2reader. + if True: + import collections.abc + collections.Iterable = collections.abc.Iterable + import nd2reader + warnings.filterwarnings('ignore', category=UserWarning, module='nd2reader') class ND2FileTileSource(FileTileSource, metaclass=LruCacheMetaclass): @@ -82,6 +91,7 @@ def __init__(self, path, **kwargs): self._pixelInfo = {} + _lazyImport() try: self._nd2 = nd2reader.ND2Reader(self._largeImagePath) except (UnicodeDecodeError,