Ojasa Mirai

Ojasa Mirai

Python

Loading...

Learning Level

🟢 BeginneršŸ”µ Advanced
Modules Import BasicsCreating ModulesImport StatementsRelative ImportsImport PathsPackages StructureNamespace PackagesPip & DependenciesModule Performance
Python/Modules Packages/Module Performance

⚔ Module Performance — Optimize Imports and Loading

Understanding how modules are loaded and imported can help you optimize your applications and reduce startup time.


šŸŽÆ Module Caching

Python caches imported modules to avoid reloading them.

import sys
import math

# First import: loads module
import requests
print("requests" in sys.modules)  # True

# Second import: uses cached version (no reload)
import requests
print("requests" in sys.modules)  # True (same object)

# Check if module is in cache
if "requests" in sys.modules:
    print("Already loaded!")

The sys.modules dictionary:

import sys

# View all loaded modules
print(len(sys.modules))  # Usually 50+

# See specific module
print(sys.modules.get("math"))
# <module 'math' from '/usr/lib/python3.9/lib-dynload/math.cpython-39-darwin.so'>

# Remove from cache to force reload (rare!)
del sys.modules["mymodule"]
import mymodule  # Reloads from disk

šŸ’” Import Timing

Measure how long imports take.

import time
import sys

# Time a single import
start = time.time()
import numpy
elapsed = time.time() - start
print(f"numpy import took: {elapsed:.4f} seconds")

# Subsequent imports are faster (cached)
start = time.time()
import numpy  # Already in sys.modules
elapsed = time.time() - start
print(f"numpy cached import took: {elapsed:.6f} seconds")  # Much faster!

Using timeit for accurate measurements:

import timeit

# Time first import
time_first = timeit.timeit(
    "import numpy",
    setup="",
    number=1
)
print(f"First import: {time_first:.4f}s")

# Time cached import
time_cached = timeit.timeit(
    "import numpy",
    setup="import numpy",
    number=1
)
print(f"Cached import: {time_cached:.6f}s")

šŸ—ļø Lazy Imports

Delay importing expensive modules until they're needed.

# āŒ Imports everything on module load (slow startup)
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import scipy

def analyze_data(filename):
    # Only uses pandas and numpy
    data = pd.read_csv(filename)
    return np.mean(data)

def plot_data(data):
    # Only uses matplotlib
    plt.plot(data)
    plt.show()

# Program starts slowly even if only analyze_data() is called!
# āœ… Lazy import (fast startup, import on first use)
def analyze_data(filename):
    import pandas as pd
    import numpy as np

    data = pd.read_csv(filename)
    return np.mean(data)

def plot_data(data):
    import matplotlib.pyplot as plt

    plt.plot(data)
    plt.show()

# Program starts quickly! Imports only when functions are called

Lazy module wrapper:

class LazyModule:
    def __init__(self, module_name):
        self.module_name = module_name
        self._module = None

    def __getattr__(self, name):
        if self._module is None:
            self._module = __import__(self.module_name)
        return getattr(self._module, name)

# Usage
numpy = LazyModule("numpy")

# numpy doesn't import until first use
array = numpy.array([1, 2, 3])  # Now it imports

šŸ“Š Import Organization Best Practices

Startup Performance:

# āŒ Slow startup - all imports at top
import requests
import numpy
import pandas
import matplotlib
import scipy
import sklearn

def quick_function():
    return "done"  # But imports all packages!

# āœ… Fast startup - lazy imports
def quick_function():
    return "done"

def data_analysis():
    import numpy
    import pandas
    # Import only when needed

šŸ’» Measuring Module Impact

import sys
import time

def measure_import_size(module_name):
    """Measure memory used by a module."""
    import importlib

    # Get size before
    before = len(sys.modules)

    start_time = time.time()
    module = importlib.import_module(module_name)
    elapsed = time.time() - start_time

    after = len(sys.modules)

    print(f"Module: {module_name}")
    print(f"Import time: {elapsed:.4f}s")
    print(f"Dependencies loaded: {after - before}")

# Test various modules
measure_import_size("math")        # Fast, minimal dependencies
measure_import_size("json")        # Medium
measure_import_size("requests")    # Slower, many dependencies

šŸ”„ Module Reloading (Advanced)

Sometimes you need to reload a module (mainly for development).

import importlib
import mymodule

# Make changes to mymodule.py...

# Reload the module
importlib.reload(mymodule)

# Now mymodule has the new code

āš ļø Warning: Reloading is tricky! Existing references aren't updated.

import importlib
import mymodule

# Old reference
old_func = mymodule.my_function

# Reload
importlib.reload(mymodule)

# This points to new version
new_func = mymodule.my_function

# But old_func still points to old version!
old_func == new_func  # False

šŸŽØ Real-World Performance Example

Web Application Startup:

# āŒ Slow startup
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_cors import CORS
from celery import Celery
import redis
import numpy as np
import pandas as pd

app = Flask(__name__)
db = SQLAlchemy(app)
CORS(app)
celery = Celery(app)
redis_client = redis.Redis()

@app.route("/health")
def health():
    return {"status": "ok"}
# āœ… Fast startup - lazy imports
from flask import Flask

app = Flask(__name__)

@app.route("/health")
def health():
    return {"status": "ok"}

@app.route("/data")
def get_data():
    # Import heavy packages only when needed
    from flask_sqlalchemy import SQLAlchemy
    import pandas as pd

    db = SQLAlchemy(app)
    data = pd.read_csv("data.csv")
    return data.to_json()

šŸ“¦ Circular Import Prevention

Circular imports can slow down module loading.

# āŒ Circular imports
# models.py
from . import views

# views.py
from . import models  # Circular!

# āœ… Solution 1: Import inside function
# models.py
class User:
    def render(self):
        from . import views  # Import when needed
        return views.render_user(self)

# āœ… Solution 2: Import at end of module
# models.py
from . import views  # Import at end

šŸ”‘ Key Takeaways

  • āœ… Python caches modules in sys.modules
  • āœ… Subsequent imports are much faster (cached)
  • āœ… Use lazy imports to speed up startup
  • āœ… Import expensive packages only when needed
  • āœ… Measure import time with timeit
  • āœ… Organize imports for performance: fast first, slow last
  • āœ… Avoid circular imports

Ready to practice? Challenges | Quiz


Resources

Python Docs

Ojasa Mirai

Master AI-powered development skills through structured learning, real projects, and verified credentials. Whether you're upskilling your team or launching your career, we deliver the skills companies actually need.

Learn Deep • Build Real • Verify Skills • Launch Forward

Courses

PythonFastapiReactJSCloud

Ā© 2026 Ojasa Mirai. All rights reserved.

TwitterGitHubLinkedIn