こんにちは、JS2IIUです。
ブログチャレンジで11日連続投稿をやってみます。先日投稿した記事「【Python】Streamlit入門編」の続編で、「Streamlit応用編」を投稿してみたいと思います。全11回の予定です。チャレンジへのお付き合い、よろしくお願いします。
はじめに
今回から始まる全11回の連載では、Pythonの簡単で強力なWebアプリケーションフレームワークであるStreamlitの様々な機能を紹介していきます。第1回目の今回は、アプリケーションのパフォーマンスを最適化するための「キャッシュ機能」に焦点を当てます。
Streamlitでは、データの読み込みや計算の結果をキャッシュすることで、同じ処理を繰り返し実行する必要がなくなり、アプリの応答速度が向上します。このキャッシュ機能を効果的に使う方法について学びましょう。
キャッシュとは?
キャッシュとは、一度計算したデータや処理結果を一時的に保存し、再度同じ計算が必要になったときにその結果を再利用する仕組みです。これにより、重い計算やデータベースへのアクセスを繰り返す必要がなくなり、アプリケーションのパフォーマンスが大幅に向上します。
Streamlitにおけるキャッシュの活用
Streamlitでは、以下の2つのデコレータを使用してキャッシュを簡単に利用することができます。
@st.cache_data: データの読み込みや計算結果をキャッシュします。主に関数の戻り値をキャッシュするのに使用します。@st.cache_resource: データベース接続やモデルの読み込みなど、リソースの初期化処理をキャッシュします。
@st.cache_data の使い方
例えば、CSVファイルからデータを読み込む関数にキャッシュを適用する方法を見てみましょう。
import streamlit as st
import pandas as pd
@st.cache_data
def load_data():
df = pd.read_csv('data.csv')
return df
data = load_data()
st.write(data)このコードでは、load_data 関数が一度実行されると、その結果がキャッシュされます。例えば、データの内容が頻繁に更新されないCSVファイルを扱っている場合、最初のロード時にキャッシュを作成しておくことで、以降のリロードが不要になり、処理が高速化されます。
@st.cache_resource の使い方
次に、リソースの初期化に対してキャッシュを適用する例を見てみましょう。
import streamlit as st
import sqlite3
@st.cache_resource
def get_connection():
conn = sqlite3.connect('database.db')
return conn
conn = get_connection()この例では、データベース接続をキャッシュしています。通常、データベース接続はコストが高いため、アプリケーションが再起動されない限りこの接続を使い回すことで、毎回の接続初期化コストが削減されます。
実際の効果の確認
実際にキャッシュの効果を確認するために、キャッシュを使った場合と使わなかった場合の処理時間を比較してみましょう。
import streamlit as st
import time
@st.cache_data
def cached_function():
time.sleep(2) # シミュレーションとして2秒の遅延
return "結果"
def non_cached_function():
time.sleep(2)
return "結果"
start_time = time.time()
st.write(cached_function())
st.write(f"キャッシュ使用時の処理時間: {time.time() - start_time:.2f}秒")
start_time = time.time()
st.write(non_cached_function())
st.write(f"キャッシュ不使用時の処理時間: {time.time() - start_time:.2f}秒")この例では、cached_function が初回実行時に2秒かかるものの、次回以降は即座に結果が返されるのに対し、non_cached_function は毎回2秒の遅延が発生します。このように、キャッシュを使うことで繰り返し処理のパフォーマンスが大幅に改善されることがわかります。
1回目の実行結果

2回目の実行結果

キャッシュの無効化とクリア
キャッシュの有効活用は重要ですが、キャッシュされたデータが古くなった場合や、データが更新されたときにキャッシュをリセットする方法も理解しておく必要があります。
キャッシュの無効化
特定の条件下でキャッシュを無効にすることもできます。例えば、データの読み込み時に動的なパラメータを使用する場合、そのパラメータの変更に応じてキャッシュを無効化することが可能です。
@st.cache_data
def load_data(file_name):
df = pd.read_csv(file_name)
return df
# キャッシュを使用せずに新しいデータを読み込みたい場合
data = load_data('new_data.csv')キャッシュのクリア
Streamlitでは、st.cache_data.clear() や st.cache_resource.clear() を使用してキャッシュをクリアすることができます。これにより、強制的にキャッシュをリセットし、新しいデータを再取得することができます。
st.cache_data.clear()
st.cache_resource.clear()これを適切なタイミングで呼び出すことで、キャッシュの更新やリセットが可能です。
キャッシュの効果的な利用シーン
キャッシュは以下のような場面で特に効果的です。
- 大量データの読み込み: 大きなファイルの読み込みやデータベースからの取得を頻繁に行う場合。
- 高コストの計算: 複雑なアルゴリズムや機械学習モデルの推論結果をキャッシュすることで、計算時間を大幅に削減。
- 外部APIの呼び出し: APIへのリクエストが頻繁に発生する場合、その結果をキャッシュして再利用する。
まとめ
第1回目では、Streamlitのキャッシュ機能を使用してアプリケーションのパフォーマンスを最適化する方法について学びました。キャッシュの活用により、アプリケーションのレスポンスが速くなり、ユーザー体験が向上します。
次回は、インタラクティブなウィジェットの応用について解説します。フォームの作成や動的なUI要素の生成について、さらに深く掘り下げていきますので、お楽しみに!
最後まで読んでいただきありがとうございました。73
補足:Streamlit応用編 記事リスト
Streamlit応用編 第1回: キャッシュ機能の活用
https://js2iiu.com/2024/08/28/streamlit-01-cache/
Streamlit応用編 第2回: インタラクティブなウィジェットの応用
https://js2iiu.com/2024/08/29/streamlit-02-widget/
Streamlit応用編 第3回: データのアップロードとダウンロード
https://js2iiu.com/2024/08/29/streamlit-03-download/
Streamlit応用編 第4回: レイアウトのカスタマイズ
https://js2iiu.com/2024/08/30/streamlit-04-layout/
Streamlit応用編 第5回: テーマのカスタマイズ
https://js2iiu.com/2024/08/31/streamlit-05-theme-custom/
Streamlit応用編 第6回: デプロイと共有
https://js2iiu.com/2024/09/01/streamlit-06-deploy/
Streamlit応用編 第7回: 認証とセキュリティ
https://js2iiu.com/2024/09/02/streamlit-07-security/
Streamlit応用編 第8回: データベースとの連携
https://js2iiu.com/2024/09/02/streamlit-08-database/
Streamlit応用編 第9回: 複雑なデータビジュアライゼーション
https://js2iiu.com/2024/09/05/streamlit-09-visualization/
Streamlit応用編 第10回: マルチページアプリの作成
https://js2iiu.com/2024/09/06/streamlit-10-multipage/
Streamlit応用編 第11回: StreamlitでAPIを作成する方法
https://js2iiu.com/2024/09/07/streamlit-11-api/
最後に、書籍のPRです。
24年9月に出版された「ハイパーモダンPython-信頼性の高いワークフローを構築するモダンテクニック」、Claudio Jolowicz著、嶋田、鈴木訳。開発環境の構築、プロジェクトの管理、テストに関して実践的な内容でとても参考になる一冊です。ぜひ手に取ってみてください。
最後まで読んでいただきありがとうございます。


コメント