1
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?

個人的アドカレAdvent Calendar 2024

Day 21

Pythonのlru_cacheを使用した関数処理時間の改善

Posted at

はじめに

同じ引数で何度も呼び出される関数がある場合、計算結果をキャッシュすることでパフォーマンスを改善できる可能性があります。
本記事では、Pythonの標準ライブラリfunctoolsモジュールに含まれる lru_cache を使用し実装例を紹介します。

環境

Python 3.12.4

lru_cacheの使い方

@lru_cache (maxsize=None) というデコレータを関数の直前に付けるだけで、その関数の結果がキャッシュされます。maxsizeパラメータは、キャッシュするアイテムの最大数を指定します。Noneを指定すると、キャッシュサイズに制限がなくなります。

from functools import lru_cache

@lru_cache(maxsize=None)
def hoge_calculation(n):
    # 時間のかかる計算をシミュレート
    result = 0
    for i in range(n):
        result += i * i
    return result

使用例

重たい処理に対して lru_cache を使用した場合と使用しない場合の違いを見てみます。
関数を10000回呼び出してみて実行時間を比較します。

import time
from functools import lru_cache

# 時間のかかる計算をシミュレート(キャッシュなし)
def sample_calculation(n):
    result = 0
    for i in range(n):
        result += i * i
    return result


# 時間のかかる計算をシミュレート(キャッシュあり)
@lru_cache(maxsize=None)
def cached_calculation(n):
    return sample_calculation(n)


# 処理時間を計測
def measure_time(func, n, iterations):
    start = time.time()
    # 10000回呼び出し
    for _ in range(iterations):
        func(n)
    end = time.time()

    print(f"{func.__name__}: {iterations} 回呼び出し完了")
    print(f"Total execution time: {end - start:.8f} seconds")
    print(f"Average time per call: {(end - start) / iterations:.12f} seconds")


# キャッシュなしで10000回呼び出し
print("\n--- キャッシュなし ---\n")
measure_time(sample_calculation, 1000, 10000)


# キャッシュありで10000回呼び出し
print("\n--- キャッシュあり ---\n")
measure_time(cached_calculation, 1000, 10000)

実行結果

キャッシュなしとありで違いを見てみます。
合計処理時間と1回あたりの処理時間は次のようになりました。

--- キャッシュなし ---
sample_calculation: 10000 回呼び出し完了
Total execution time: 0.32430840 seconds
Average time per call: 0.000032430840 seconds

--- キャッシュあり ---

cached_calculation: 10000 回呼び出し完了
Total execution time: 0.00099969 seconds
Average time per call: 0.000000099969 seconds

キャッシュなしの場合は10000回の呼び出しに約0.32秒(1回あたり約0.000032秒)かかっているのに対し、キャッシュありの場合は同じ10000回の呼び出しが約0.001秒(1回あたり約0.0000001秒)で完了しています。lru_cacheを使用することで処理時間が改善されたことを確認できました。

1
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
1
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?