DataLens

Caching dengan st.cache_data dan st.cache_resource

Berhenti memuat ulang file dan menjalankan ulang query di setiap klik dengan caching hasilnya, dan pelajari cache mana yang dipakai, cara kerja cache key dan kapan harus mengosongkannya.

Level: Menengah · 7 menit baca

Latihan modul ini

Soal-soal untuk pelajaran ini berjalan di browser-mu dan langsung mengecek jawabanmu.

Idenya

Model rerun punya harga: setiap klik menjalankan seluruh script, termasuk bagian-bagian yang lambat. Kalau memuat datamu butuh 3 detik, setiap gerakan slider butuh 3 detik. Caching memperbaikinya: Streamlit mengingat hasil sebuah fungsi, dan saat fungsi itu dipanggil lagi dengan argumen yang sama, langsung mengembalikan hasil yang tersimpan alih-alih menjalankan fungsinya lagi.

Analogi

Cache adalah catatan tempel di kulkas berisi jawaban kemarin. Sebelum kamu mengulang perhitungan yang panjang, kamu memeriksa apakah jawaban untuk pertanyaan yang persis sama sudah tertulis.

st.cache_data: untuk data

Memuat file CSV besar bisa memakan beberapa detik, dan karena seluruh script dijalankan ulang setiap kali widget berubah, file itu dimuat lagi di setiap klik. Solusinya adalah menaruh pemuatannya di sebuah fungsi lalu menandainya dengan @st.cache_data. Streamlit lalu mengingat hasilnya dan memberikannya kembali dengan instan lain kali:

import streamlit as st
import pandas as pd


@st.cache_data
def load_sales(path):
    st.write("Loading data from disk...")      # hanya terlihat saat fungsinya benar-benar berjalan
    return pd.read_csv(path)


sales = load_sales("sales.csv")
st.write(f"{len(sales)} order lines loaded")
st.slider("Pick a number", 0, 10, 5)

Di eksekusi pertama kamu melihat "Loading data from disk...". Geser slider-nya: pesannya hilang, karena load_sales("sales.csv") dijawab dari cache. Isi fungsimu hanya berjalan saat cache tidak punya jawabannya.

st.cache_data untuk fungsi yang mengembalikan data: DataFrame, list, dict, angka, hasil pemanggilan API dan query database. Setiap pemanggilan mendapat salinan dari nilai yang di-cache, jadi kode yang mengubah DataFrame yang dikembalikan tidak bisa merusak cache-nya.

Cara kerja cache key

Bagaimana kalau jawaban fungsinya bergantung pada argumennya? Revenue per kategori dan revenue per channel adalah hasil yang berbeda. Cache menanganinya dengan menyimpan satu hasil per kombinasi argumen:

import streamlit as st
import pandas as pd


@st.cache_data
def revenue_by(column):
    sales = pd.read_csv("sales.csv")
    completed = sales[sales["status"] == "completed"]
    return completed.groupby(column, as_index=False)["revenue"].sum()


choice = st.radio("Group by", ["category", "channel", "city"], horizontal=True)
st.dataframe(revenue_by(choice), hide_index=True)

Pertama kali setiap opsi dipilih, fungsinya berjalan; setelah itu, berpindah bolak-balik menjadi instan. Argumen adalah bagian dari key, jadi berikan semua hal yang memengaruhi hasilnya sebagai argumen. Fungsi yang diam-diam membaca variabel global atau nilai widget tidak akan sadar saat nilai itu berubah, dan akan mengembalikan hasil yang basi.

st.cache_resource: untuk koneksi dan model

Beberapa hal tidak boleh disalin: koneksi database, model machine learning, HTTP client. Semuanya mahal untuk dibuat dan dimaksudkan untuk dibagi:

import streamlit as st
import sqlite3


@st.cache_resource
def get_connection():
    conn = sqlite3.connect(":memory:", check_same_thread=False)
    conn.execute("CREATE TABLE visits (city TEXT)")
    return conn


conn = get_connection()
st.write("Same connection object on every rerun:", id(conn))
st.cache_datast.cache_resource
Dipakai untukdata: DataFrame, hasil query, respons APIresource: koneksi, model, client
Mengembalikansalinan baru setiap pemanggilanobjek yang sama setiap pemanggilan
Dibagi antar penggunaya (masing-masing mendapat salinan)ya (objek yang sama)
Ide utama

Data yang akan kamu baca dan ubah → cache_data. Sesuatu yang akan kamu pakai (untuk terhubung, untuk memprediksi) → cache_resource.

Saat data yang di-cache menjadi usang

Hasil yang di-cache bertahan sampai aplikasi di-restart. Untuk data yang berubah (order hari ini), beri cache-nya umur:

import streamlit as st
import pandas as pd


@st.cache_data(ttl=600)          # detik: refresh paling sering setiap 10 menit
def load_orders():
    return pd.read_csv("sales.csv")


orders = load_orders()
if st.button("Refresh now"):
    load_orders.clear()           # lupakan hasil cache untuk fungsi ini
    st.rerun()
st.write(f"{len(orders)} rows")

(Simulator di situs ini tidak membuat cache ttl kedaluwarsa berdasarkan waktu; parameternya diterima supaya kodemu berjalan tanpa perubahan di Streamlit sungguhan.)

Apa yang tidak perlu di-cache

Mengapa ini penting untuk kode yang bersih

Caching menghargai kebiasaan fungsi bersih dari track Python: fungsi yang hasilnya hanya bergantung pada argumennya dan yang tidak punya efek samping persis yang bisa di-cache dengan benar. Kalau sebuah fungsi sulit di-cache, itu sering menjadi tanda bahwa ia mengerjakan dua tugas (memuat dan mencatat log, menghitung dan menampilkan). Pecah fungsinya, cache bagian yang murni.

Rangkuman

Latihan modul ini

Soal-soal untuk pelajaran ini berjalan di browser-mu dan langsung mengecek jawabanmu.