0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

#0071(2024/03/12)Lazy loading

Last updated at Posted at 2025-03-12

PythonにおけるLazy Loading(遅延読み込み)のトライ

Pythonでデータ処理や画像処理を行う際、「Lazy Loading(遅延読み込み)」という手法を使うと、効率的にメモリを管理し、大規模なデータ処理を快適に行えるようになります。本記事では、Lazy Loadingの概要と、一括読み込みとの違いを実際のテスト結果をもとに解説します。

🔹 Lazy Loadingとは?

Lazy Loading(遅延読み込み)とは、必要になるまでデータをメモリに読み込まない処理方式です。すべてのデータを一度にメモリ上に展開する「一括読み込み」とは対照的で、メモリ効率が良く、大規模データや大量の画像ファイルを扱う際に有効な手法です。

🔹 一括読み込みとの違い

  • 一括読み込み: 全データを一度にメモリ上に読み込み、処理を開始します。メモリ使用量が非常に多くなり、大量のデータを扱うとメモリ不足になる可能性があります。
  • Lazy Loading: 必要なデータを逐次的に読み込むため、メモリの消費を抑えられます。メモリ使用量が少なく、大量のデータ処理にも対応できます。

🔹 PythonによるLazy Loadingの実例

画像を用いたサンプルコードでLazy Loadingと一括読み込みの違いを検証します。

サンプルコード

import os
import tempfile
from PIL import Image
from memory_profiler import profile

def create_mock_images(num_images, image_size=(100, 100), directory=None):
    if directory is None:
        directory = tempfile.mkdtemp()
    image_paths = []
    for i in range(num_images):
        img = Image.new("RGB", image_size, color=(i % 256, (i * 2) % 256, (i * 3) % 256))
        path = os.path.join(directory, f"mock_{i}.jpg")
        img.save(path, "JPEG")
        image_paths.append(path)
    return image_paths

def load_images_lazy(image_paths):
    for path in image_paths:
        with Image.open(path) as img:
            img.load()
            yield img.copy()

def load_images_all(image_paths):
    images = []
    for path in image_paths:
        with Image.open(path) as img:
            img.load()
            images.append(img.copy())
    return images

@profile
def process_images_lazy(image_paths):
    for img in load_images_lazy(image_paths):
        _ = img.size

@profile
def process_images_all(image_paths):
    images = load_images_all(image_paths)
    for img in images:
        _ = img.size

if __name__ == "__main__":
    num_images = 100000
    image_paths = create_mock_images(num_images)
    print(f"Mock images created in directory: {os.path.dirname(image_paths[0])}")

    print("Processing images with lazy loading:")
    process_images_lazy(image_paths)

    print("Processing images with all-at-once loading:")
    process_images_all(image_paths)

🔹 実行結果(メモリ使用量比較)

Lazy Loadingの場合

Line #    Mem usage    Increment  Occurrences   Line Contents
=============================================================
    36     53.4 MiB     53.4 MiB           1   @profile
    39     53.6 MiB      0.2 MiB         101       for img in load_images_lazy(image_paths):
    41     53.6 MiB      0.0 MiB         100           _ = img.size

一括読み込みの場合

Line #    Mem usage    Increment  Occurrences   Line Contents
=============================================================
    43     53.6 MiB     53.6 MiB           1   @profile
    46     57.5 MiB      3.9 MiB           1       images = load_images_all(image_paths)
    47     57.5 MiB      0.0 MiB         101       for img in images:
    48     57.5 MiB      0.0 MiB         100           _ = img.size

🔹 Lazy Loadingのすごさまとめ

Lazy Loadingを使用すると、

  • 一度にメモリを大量に消費することなく、安定した処理が可能になる。
  • 特に画像や大規模データを大量に扱う際、メモリ不足を避けられる。
  • スケーラブルで効率的な処理が可能になる。

大規模データ処理を行う際はLazy Loadingの活用を検討すると、効率的で安定したアプリケーションを構築できます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?