【Streamlit】キャッシングでアプリのパフォーマンスを向上させる:@st.cache_data, @st.cache_resource

Streamlit
この記事は約5分で読めます。

こんにちは、JS2IIUです。
今回はStreamlitのキャッシュ機能についてみていきます。処理速度を改善して、ユーザーにとって快適なサービスを提供できるようになります。今回もよろしくお願いします。

はじめに

Streamlitでアプリを作っていて、以下のような経験はありませんか?

  • 大きなデータを毎回読み込んで遅い
  • 重たい計算処理が何度も走ってしまう

こうした問題を解決して、アプリをサクサク動かす方法が「キャッシング」です。
この記事では、Streamlitでよく使われるキャッシュ機能 @st.cache_data@st.cache_resource の使い方を、初心者の方でも理解しやすいように、具体例を使って丁寧に解説します。

キャッシュとは?

キャッシュの基本概念

キャッシュとは、一度行った処理の結果を保存しておき、次に同じ処理が必要になったときに、再実行せずに保存済みの結果を再利用する仕組みです。

例えば、大きなCSVファイルを読み込むのに毎回10秒かかるとしたら、キャッシュを使えば初回だけ読み込み、次回からは即座に結果を再利用できます。

Streamlitには、このキャッシュ機能を簡単に使える2つのデコレーターが用意されています:

  • @st.cache_data: データ処理・計算結果向け
  • @st.cache_resource: モデル・外部リソース向け

@st.cache_data の使い方

使いどころ

  • データの読み込み(CSV/Excelなど)
  • 重い計算処理

基本構文

Python
@st.cache_data
def 関数名():
    # 時間のかかる処理
    return 結果

実践例:CSVファイルの読み込み

Python
import streamlit as st
import pandas as pd

@st.cache_data
def load_data():
    st.write("📦 データを読み込んでいます...")
    df = pd.read_csv("https://raw.githubusercontent.com/mwaskom/seaborn-data/master/iris.csv")
    return df

st.title("Irisデータセットの表示")
df = load_data()
st.dataframe(df)

解説

このコードでは、初回のみCSVファイルが読み込まれ、”📦 データを読み込んでいます…” が表示されます。
2回目以降の実行では、キャッシュからデータが取得され、読み込み処理がスキップされます。

@st.cache_resource の使い方

使いどころ

  • 機械学習モデルの読み込み
  • データベース接続など外部リソースの初期化

実践例:重たい処理のキャッシュ

Python
import streamlit as st
import time

@st.cache_resource
def load_model():
    st.write("🤖 モデルを読み込んでいます...")
    time.sleep(5)  # 擬似的に時間のかかる処理
    return "モデル"  # 実際はモデルオブジェクトを返す

st.title("モデルのキャッシュデモ")
model = load_model()
st.success(f"取得したリソース: {model}")

解説

このコードでは、初回実行時に5秒の遅延がありますが、2回目以降はキャッシュが使われ即座に表示されます。

よくあるエラーと対処法

1. キャッシュ対象の関数でStreamlitのAPIを呼んでしまう

エラー内容: st.write などのUI操作をキャッシュ関数の中で使うと警告が出ることがあります。

対処法: 処理部分とUI部分を分ける。

NG例:

Python
@st.cache_data
def load():
    st.write("読み込み中...")  # UI操作 → NG
    return 100

OK例:

Python
@st.cache_data
def load():
    return 100

st.write("読み込み中...")
data = load()

2. キャッシュが効かない(毎回処理が走る)

原因: 関数の引数が毎回異なる場合、キャッシュは再利用されません。

例:

Python
@st.cache_data
def compute(x):
    return x ** 2

value = compute(time.time())  # 毎回異なる値 → キャッシュされない

対処法: 引数が毎回同じになるように工夫する。

処理時間の比較で効果を確認

Python
import streamlit as st
import time

@st.cache_data
def slow_function():
    time.sleep(3)
    return "完了"

st.title("キャッシュ効果の確認")
start = time.time()
result = slow_function()
elapsed = time.time() - start

st.write(f"結果: {result}")
st.write(f"処理時間: {elapsed:.2f}秒")

実行結果

  • 初回:処理時間 約3秒
  • 2回目以降:処理時間 約0秒(キャッシュ使用)

まとめ

  • @st.cache_dataデータの読み込み・計算用
  • @st.cache_resourceモデルやリソースの初期化用
  • キャッシュを使うと、アプリの動作が高速化し、ユーザー体験が向上
  • よくあるエラーに注意し、正しく使えば効果は絶大!

参考リンク

最後まで読んでいただきありがとうございました。

コメント

タイトルとURLをコピーしました