Cara menyimpan kamus dengan python

Dot Net Perls adalah kumpulan contoh kode yang telah diuji. Halaman terus diperbarui agar tetap terkini, dengan kebenaran kode sebagai prioritas utama

Sam Allen sangat tertarik dengan bahasa komputer. Di masa lalu, karyanya telah direkomendasikan oleh Apple dan Microsoft dan dia pernah belajar komputer di universitas selektif di Amerika Serikat

Halaman ini terakhir diperbarui pada 16 Sep 2022 (tautan edit)

Caching adalah istilah umum yang digunakan untuk menyimpan beberapa data sementara di tempat yang dapat dibaca lebih cepat daripada membacanya dari sumber (database, sistem file, layanan, dll). Cache lapisan penyimpanan adalah salah satu subset dari sumber atau hasil pra-perhitungan dari beberapa komputasi berat. Data dalam cache umumnya disimpan dalam perangkat keras akses cepat seperti RAM dan mesin dalam memori. Dengan demikian, caching memungkinkan Anda meningkatkan throughput sistem secara keseluruhan karena lebih banyak permintaan baca dapat ditangani per satuan waktu

caching (dibuat oleh Xiaoxu Gao)

Kapan kita membutuhkan caching?

Ketika datang ke masalah kinerja, kami biasanya mengidentifikasi masalah sebagai terikat CPU atau terikat I/O. Caching dapat bermanfaat dalam kedua kasus

Menyimpan data yang dihitung sebelumnya

Contoh mempercepat program yang terikat CPU adalah meng-cache hasil yang dihitung sebelumnya untuk menghindari perhitungan berulang. Kita dapat menggunakannya untuk menyelesaikan masalah Fibonacci menggunakan metode rekursif. Inilah pohon rekursif

pohon rekursif Fibonacci (dibuat oleh Xiaoxu Gao)

Algoritme dasar mengharuskan Anda untuk membuat kode fungsi rekursif yang memanggil dirinya sendiri sebanyak yang diperlukan. Ambil grafik ini sebagai contoh, untuk menghitung f5, fungsi harus memanggil dirinya sendiri 15 kali, termasuk 5 kali untuk simpul f1, 3 kali untuk simpul f0, 3 kali untuk simpul f2, dll. Waktu yang dibutuhkan tumbuh secara eksponensial karena fungsi menghitung banyak submasalah identik berulang kali

Salah satu teknik untuk membuat algoritme lebih efisien disebut memoisasi. Memoisasi mempercepat algoritme dengan menyimpan hasil yang dihitung sebelumnya dalam cache. Dengan demikian, fungsi hanya perlu mencari hasil dari sebuah node tanpa menjalankan komputasi lagi. Jika Anda tertarik dengan masalah Fibonacci, Anda dapat membaca artikel ini di Real Python

Menyimpan data yang paling sering diminta

Banyak lapisan penyimpanan seperti database dan sistem file dapat menjadi faktor yang paling berdampak pada kinerja keseluruhan program Anda karena IOPS (operasi input/output per detik) yang rendah. Untuk mempercepat program terikat I/O, cache membuat lapisan penyimpanan di depan lokasi penyimpanan asli (database, sistem file, dll) untuk pengambilan data yang jauh lebih cepat. Caching dapat diterapkan melalui berbagai lapisan teknologi

  • Sistem operasi — Lebih lambat membaca data dari tingkat yang lebih rendah daripada dari tingkat yang lebih tinggi. Cache di OS adalah untuk memastikan bahwa data yang paling sering diminta berada di level tertinggi
  • Basis data — Sebagian besar basis data seperti MySQL menggunakan cache internal untuk menyimpan data panas di memori atau hasil kueri yang mahal. Ini melayani respons terhadap permintaan basis data mengingat data sudah ada di cache. Ini secara dramatis meningkatkan kinerja dengan mengurangi pemanfaatan sumber daya pada mesin database. Meskipun sepenuhnya dikelola oleh database, memahami mekanisme ini dapat membantu dalam men-debug masalah kinerja
  • Aplikasi — Pengembang dapat mengimplementasikan solusi caching khusus di lapisan aplikasi yang digerakkan oleh aktivitas. Jika Anda tidak puas dengan solusi caching bawaan di database, Anda dapat memiliki cache lain di depan database Anda yang menyimpan data panas dan tanggal kedaluwarsanya sesuai kebutuhan Anda
  • Caching Web — Caching digunakan secara luas dalam aplikasi web. Berbagai strategi caching dapat digunakan baik di server maupun di sisi klien. Server biasanya menggunakan proxy web untuk mempertahankan respons web. Klien (mis. g. browser) biasanya meng-cache aset web seperti gambar, halaman HTML, sesi HTTP untuk memberikan pengalaman pengguna yang lebih baik di semua server web dan perangkat
  • CDN (Jaringan Pengiriman Konten) — Saat lalu lintas web Anda tersebar secara geografis, menyalin seluruh infrastruktur ke setiap lokasi baru itu mahal. CDN menyediakan kemampuan untuk mengirimkan salinan konten web yang di-cache seperti video dan halaman web ke pelanggan Anda di mana saja

Apa saja strategi caching?

Sebagian besar cache dirancang sebagai pasangan kunci-nilai di mana kunci cache adalah pengidentifikasi unik untuk setiap objek dalam cache. Hit cache terjadi ketika permintaan menghasilkan kunci cache yang cocok dan objek akan dikembalikan sebagai respons. Saat mengimplementasikan cache, kita harus memahami beberapa karakteristik dan strategi caching yang umum

Cache dirancang untuk aplikasi berat baca

Seperti yang sudah jelas sekarang bahwa caching adalah solusi untuk membaca cepat. Ini sebagian besar bermanfaat untuk program yang melakukan operasi baca berat. Untuk mencapai performa terbaik, operasi baca harus memiliki kompleksitas waktu O(1). Jika Anda terbiasa dengan struktur data dasar, Anda harus mengetahui peta hash — yaitu kamus dengan Python. Nilai kunci yang diberikan dalam kamus dapat ditimpa oleh set operasi terbaru yang juga memiliki kompleksitas waktu O(1)

cache = {}
cache["user1"] = "res1"

Namun, ada beberapa masalah dengan implementasi ini. Dalam kasus terburuk (meskipun sangat jarang), masalah tabrakan utama akan menghasilkan kompleksitas waktu O(n) untuk operasi baca. Masalah lainnya adalah Anda tidak dapat memasukkan semuanya ke dalam cache dalam memori karena pada akhirnya akan meledakkan memori, jadi Anda harus memutuskan apa yang harus disimpan oleh cache

Menyimpan konten berdasarkan waktu pembuatannya

Cara untuk mengontrol ukuran cache adalah dengan memiliki semacam mekanisme pembersihan otomatis. Saat memasukkan pasangan nilai kunci baru ke dalam cache, kunci tersebut ditetapkan dengan nilai TTL (time-to-live). Ini adalah nilai integer yang menentukan jumlah detik hingga kunci kedaluwarsa. Dengan kata lain, pasangan akan dihapus setelah TTL detik untuk menjaga cache pada ukuran yang dapat diatur. Ini menghindari mengacaukan cache dengan data yang terlalu basi

Pemilihan TTL yang tepat didasarkan pada sensitivitas waktu objek. Secara umum, TTL yang lebih tinggi ditetapkan untuk data yang tidak sering berubah atau klien lebih toleran terhadap data usang. TTL yang lebih rendah disetel untuk data sensitif waktu seperti pasar saham dan cuaca dengan memaksa cache memvalidasi ulang konten lebih sering

Untuk membuat cache dengan TTL, kita dapat menginstal paket cachetools. Dalam contoh ini, cache menyimpan data cuaca yang diambil dari OpenWeatherMap dan menyegarkan cache setiap 10 menit

Contoh tembolok TTL

Di balik layar, fungsi pertama memanggil API dan menyimpan respons di cache dengan TTL disetel ke 10 menit. Dengan demikian, fungsi kedua memakan waktu lebih sedikit karena mengambil data langsung dari cache. Fungsi ketiga dijalankan ketika kunci telah kedaluwarsa, sehingga memanggil API lagi dan menyegarkan data cuaca Amsterdam di cache

TTL banyak digunakan dalam konteks CDN. Ini mengontrol kecepatan penyegaran sumber daya situs web, idealnya memastikan bahwa klien tidak melihat konten yang terlalu basi sambil meningkatkan kecepatan memuat halaman. TTL juga merupakan pengaturan server DSN yang memberi tahu cache berapa lama menyimpan catatan DNS sebelum mencari lagi dari server nama

Menyimpan konten berdasarkan pola aksesnya — LRU & LFU

Selain waktu, faktor penting lainnya untuk memutuskan kapan mengeluarkan objek dari cache adalah pola aksesnya. 2 strategi umum digunakan saat cache penuh

  • LRU (Least Lastly used) — Buang item yang paling jarang digunakan terlebih dahulu. Itu memesan item dalam urutan penggunaan. Setiap kali Anda mengakses objek, algoritme akan memindahkannya ke bagian atas cache. Dengan cara ini, algoritme dapat dengan cepat mengidentifikasi item mana yang paling lama tidak diakses
  • LFU (Lease Frequently used) — Buang item yang paling jarang digunakan terlebih dahulu. Alih-alih menghapus data yang paling jarang digunakan, ini akan menghapus data yang paling jarang digunakan. Itu mungkin membuang data yang baru saja digunakan tetapi tidak digunakan sesering data lainnya

Misalnya, jika Anda menerapkan cache untuk menyimpan riwayat browser dan Anda lebih tertarik pada halaman yang baru dikunjungi, cache LRU lebih berguna. Di sisi lain, jika Anda menggunakan cache untuk menyimpan bookmark browser Anda, maka LFU lebih berguna karena pengguna dapat dengan cepat membuka halaman favorit mereka.

Python menyediakan pustaka bawaan untuk cache LRU. Cache menyimpan hingga maxsize panggilan terakhir. Dalam contoh ini, ukuran cache adalah 1. Dengan melihat log, 3 fungsi pertama sebenarnya memanggil API karena semuanya meminta data yang berbeda dari fungsi sebelumnya. Hanya fungsi terakhir yang memanfaatkan cache karena mengambil objek yang sama dengan fungsi sebelumnya

Contoh cache lru

Selanjutnya, mari kita periksa penerapan cache LRU untuk memahami mengapa ini menjadi strategi caching yang begitu populer. Sebagai cache, ia harus hemat waktu dalam arti bahwa kompleksitas waktu harus O(1) untuk semua operasi

Peta hash adalah struktur data yang baik untuk menyimpan pasangan kunci-nilai dengan kompleksitas waktu yang rendah. Dalam cache LRU, kita membutuhkan struktur data lain untuk menjaga urutan penggunaan. Seluruh proses melibatkan langkah-langkah berikut

  • Cari item di peta hash. Peta hash menyimpan objek dan urutan penggunaannya
  • Pindahkan objek ke kepala garis dan objek lainnya harus dipindahkan ke belakang sesuai dengan itu. Perlu dicatat bahwa kompleksitas waktu harus O(1) dalam manuver ini. Anda dapat berhenti sebentar di sini dan memikirkan struktur data mana yang paling cocok
  • Jika item tidak ada di peta hash, item tersebut akan ditambahkan ke bagian atas baris. Jika cache penuh, kita perlu mengeluarkan item yang paling jarang digunakan — ujung baris. Kompleksitas waktu seharusnya O(1) juga

Struktur data mana yang ada di pikiran Anda? . Sebuah LinkedList tunggal, bagaimanapun, hanya membutuhkan waktu O(1). Tetapi menghapus simpul ekor membutuhkan waktu O(n) karena perlu melintasi seluruh LinkedList

Jadi solusi terbaik adalah menggunakan LinkedList ganda

Contoh cache LRU (dibuat oleh Xiaoxu Gao)

Peta hash menyimpan node Daftar Tertaut yang sesuai. Kompleksitas waktu untuk memindahkan sebuah node ke bagian atas list adalah O(1). Karena ini adalah Doubly Linked List, menghapus simpul ekor juga membutuhkan waktu O(1).

Berikut adalah cara untuk mengimplementasikan cache LRU dengan Python

Implementasi cache Lru

LFU bekerja dengan cara yang mirip dengan cache LRU, tetapi menghapus data berdasarkan frekuensi penggunaannya. Jika ada beberapa item dengan frekuensi yang sama, item yang terakhir digunakan akan dikeluarkan. Dibandingkan dengan cache LRU, membutuhkan peta hash tambahan untuk menyimpan informasi frekuensi. Kuncinya adalah frekuensi, nilainya adalah daftar item dengan frekuensi tersebut dan diurutkan berdasarkan waktu akses. Dalam implementasinya, saya juga menggunakan Linked List ganda. Tapi bagian ini bisa diganti dengan Python yang diimplementasikan menggunakan struktur data yang sama di bawah tenda

Cache Lfu (Dibuat oleh Xiaoxu Gao)

Implementasi Lfu cahce

Simpan konten berdasarkan waktu pembuatan dan pola aksesnya

Masalah dengan cache LRU/LFU adalah tidak akan pernah mengambil pembaruan dari sumber jika data diminta berulang kali. Untuk mengatasi masalah ini, kita dapat menambahkan nilai TTL. Jika permintaan mencoba mengakses data kedaluwarsa, fungsi akan mengambil pembaruan dari sumber dan menyegarkan cache. Kita dapat mengimplementasikannya dengan membuat dekorator di atas @lru_cache

Pada fungsi yang terakhir, meskipun cache belum penuh, fungsi tersebut tetap memanggil API karena data kadaluarsa. Strategi ini berguna ketika pola waktu dan akses keduanya relevan. Misalnya, saya ingin mendesain cache untuk menyimpan tweet terbaru dari pengguna Twitter. Cache LFU memastikan bahwa hanya tweet pengguna populer yang disimpan dalam cache dan nilai TTL memastikan bahwa cache tidak berisi tweet yang terlalu basi

Bagaimana cara mengintegrasikan cache ke dalam sistem?

Sejauh ini, kami telah membahas desain internal dan kebijakan pengusiran cache. Akhirnya, kita perlu mengintegrasikan cache ke dalam aplikasi kita. Ada beberapa pola yang dapat diterapkan tergantung pada jenis aplikasi Anda

Bacalah

Bacalah (Dibuat oleh Xiaoxu Gao)

Ini adalah pola yang paling umum digunakan. Saat menerima permintaan, aplikasi mencoba menemukan kecocokan di cache. Jika menemukan data, maka segera mengembalikan data tersebut. Jika tidak, ia akan pergi ke basis data yang mendasarinya untuk mengambilnya dan memuatnya ke dalam cache

Dalam pola ini, latensi untuk permintaan awal akan tinggi karena seringnya cache hilang

Menulis melalui

Menulis melalui (Dibuat oleh Xiaoxu Gao)

Write through membalikkan urutan bagaimana cache diisi. Setiap penulisan pertama kali dilakukan ke cache sebelum ke sumbernya. Ini berarti bahwa cache selalu disinkronkan dengan sumbernya. Aplikasi tidak perlu membaca data dari sumbernya

Karena cache disinkronkan dengan sumbernya, kemungkinan besar data dapat ditemukan di cache. Sehingga menghasilkan kinerja yang lebih baik. Namun, kerugiannya adalah semua data termasuk data yang jarang diminta juga disimpan di cache, sehingga menghasilkan cache yang besar dan mahal. Dan sinkronisasi antara cache dan sumber adalah proses sinkron yang dapat mengakibatkan latensi tinggi

Merupakan hal yang umum untuk menggunakan pola tulis dan baca. Misalnya, data pertama kali ditulis ke cache dan nilai TTL diatur agar tetap relevan dan ramping. Jika data yang dihapus pernah diminta lagi, itu dapat diambil kembali dari sumbernya menggunakan pola baca-tayang

Tulis di Belakang

Tulis di belakang (Dibuat oleh Xiaoxu Gao)

Ini mirip dengan pola tulis. Aplikasi pertama menulis data ke cache. Namun setelah itu aplikasi langsung kembali ke proses utama. Proses lain akan berjalan secara berkala untuk menyinkronkan data antara cache dan sumbernya. Berbeda dengan write-through, pencadangan antara cache dan sumber merupakan proses asinkron

Ini lebih efektif untuk kasus di mana kami tidak ingin menanggung biaya latensi tinggi untuk menulis ke sumber setiap kali dan proses sinkronisasi cukup andal. Namun, pola ini memerlukan proses pencadangan yang kuat dari cache ke sumber untuk memastikan data tidak hilang

Segarkan ke depan

Segarkan ke depan (Dibuat oleh Xiaoxu Gao)

Dalam pola ini, cache dikonfigurasi untuk memuat ulang data secara otomatis dan asinkron dari sumber sebelum kedaluwarsa. Dengan demikian, aplikasi akan selalu mengambil data dari cache. Jika terjadi cache yang jarang terjadi, itu akan melakukan pembacaan sinkron dari sumber dan menyegarkan cache

Refresh-ahead berguna untuk aplikasi yang banyak dibaca. Nilai tetap segar di cache dan masalah pemuatan ulang yang berlebihan dari sumber dapat dihindari

Secara umum, refresh-ahead dan read-through didesain untuk aplikasi read-only. Refresh-ahead lebih efektif dengan latensi rendah, tetapi memerlukan mekanisme dalam cache untuk memutuskan kapan dan apa yang akan dimuat dari sumber. Read-through mudah diterapkan, tetapi kita harus menanggung latensi tinggi dalam permintaan awal karena sebagian besar dari permintaan tersebut akan langsung menuju ke sumbernya

Untuk aplikasi baca/tulis, write-through dan write-behind sama-sama berguna. Demikian pula, write-through relatif mudah diimplementasikan tetapi menghasilkan latensi tinggi karena pencadangan sinkron antara cache dan sumber. Meskipun write-behind memiliki latensi rendah tetapi perlu memastikan tidak ada yang hilang saat membuang cache ke sumbernya

Kesimpulan

Dalam artikel ini, kita telah berbicara tentang beberapa teori seputar caching termasuk apa itu caching, kapan kita membutuhkannya, dan berbagai strategi dan pola caching. Kami juga telah melihat penerapan cache TTL, cache LRU, dan cache LFU dengan Python. Saya harap Anda merasa berguna. Bersulang

Apa itu cache LRU dalam kamus Python?

Cache LRU (Terakhir Digunakan) membuang item yang paling jarang digunakan terlebih dahulu . Algoritme ini membutuhkan pelacakan tentang apa yang digunakan kapan, yang mahal jika seseorang ingin memastikan algoritme selalu membuang item yang paling jarang digunakan.

Bagaimana cara menerapkan memcache dengan Python?

Menginstal memcache . Jika Anda menjalankan Linux, Anda dapat menginstalnya menggunakan apt-get install memcached atau yum install memcached . Ini akan menginstal memcache dari paket pre-built tetapi Anda juga dapat mem-cache build dari sumber, seperti yang dijelaskan di sini.

Apa itu kamus Python yang kedaluwarsa?

Kedaluwarsa Dict . Inti dari perpustakaan adalah kelas ExpiringDict yang merupakan kamus terurut dengan nilai kedaluwarsa otomatis untuk tujuan caching. Kedaluwarsa terjadi pada akses apa pun, objek dikunci selama pembersihan dari nilai kedaluwarsa. expiringdict is a Python caching library. The core of the library is ExpiringDict class which is an ordered dictionary with auto-expiring values for caching purposes. Expiration happens on any access, object is locked during cleanup from expired values.

Apa perbedaan antara lru_cache dan Cached_property?

cached_property mirip dengan lru_cache dalam arti cache hasil dari pemanggilan fungsi yang mahal. Satu-satunya perbedaan di sini adalah bahwa ini hanya dapat digunakan pada metode , yang berarti bahwa fungsi dimiliki oleh suatu objek. Selain itu, mereka hanya dapat digunakan pada metode yang tidak memiliki parameter lain selain diri.