17 ноября 2020

🧩 ΠšΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π² Python: Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ LRU

ΠŸΠΈΡˆΡƒ, ΠΏΠ΅Ρ€Π΅Π²ΠΎΠΆΡƒ ΠΈ ΠΈΠ»Π»ΡŽΡΡ‚Ρ€ΠΈΡ€ΡƒΡŽ IT-ΡΡ‚Π°Ρ‚ΡŒΠΈ. На proglib написал 140 ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»ΠΎΠ². УвлСкаюсь Python, Π²Π΅Π±ΠΎΠΌ ΠΈ Data Science. ΠžΡ‚ΠΊΡ€Ρ‹Ρ‚ ΠΊ Π΄ΠΈΠ°Π»ΠΎΠ³Ρƒ – ссылки Π½Π° соцсСти ΠΈ мСссСндТСры: https://matyushkin.github.io/links/ Если понравился ΡΡ‚ΠΈΠ»ΡŒ излоТСния, упорядочСнный список ΠΏΡƒΠ±Π»ΠΈΠΊΠ°Ρ†ΠΈΠΉ β€” https://github.com/matyushkin/lessons
Π§Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΡ‚ΡŒ LRU-ΠΊΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π² Python, достаточно Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ всСго Π΄Π²Π΅ строчки – ΠΈΠΌΠΏΠΎΡ€Ρ‚ ΠΈ объявлСниС Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€Π° @lru_cache. ΠŸΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅ΠΌ Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°Ρ…, ΠΊΠ°ΠΊ ΠΈ Π·Π°Ρ‡Π΅ΠΌ Π΅Π³ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ.
🧩 ΠšΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π² Python: Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ LRU

Π­Ρ‚Π° публикация – Π½Π΅Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ сокращСнный ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄ ΡΡ‚Π°Ρ‚ΡŒΠΈ Π‘Π°Π½Ρ‚ΡŒΡΠ³ΠΎ Π’Π°Π»Π΄Π°Ρ€Ρ€Π°ΠΌΠ° Caching in Python Using the LRU Cache Strategy. ΠŸΠ΅Ρ€Π΅Π²Π΅Π΄Π΅Π½Π½Ρ‹ΠΉ тСкст Ρ‚Π°ΠΊΠΆΠ΅ доступСн Π² Π²ΠΈΠ΄Π΅ Π±Π»ΠΎΠΊΠ½ΠΎΡ‚Π° Jupyter.

***

ΠšΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ – ΠΎΠ΄ΠΈΠ½ ΠΈΠ· ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΡ€ΠΈ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΠΌ использовании Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ускоряСт Ρ€Π°Π±ΠΎΡ‚Ρƒ ΠΈ сниТаСт Π½Π°Π³Ρ€ΡƒΠ·ΠΊΡƒ Π½Π° Π²Ρ‹Ρ‡ΠΈΡΠ»ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ рСсурсы. Π’ ΠΌΠΎΠ΄ΡƒΠ»Π΅ стандартной Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ Python functools Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ @lru_cache, Π΄Π°ΡŽΡ‰ΠΈΠΉ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΊΡΡˆΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π²Ρ‹Π²ΠΎΠ΄ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ ΡΡ‚Ρ€Π°Ρ‚Π΅Π³ΠΈΡŽ Least Recently Used (LRU, «вытСснСниС Π΄Π°Π²Π½ΠΎ Π½Π΅ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Ρ…Β»). Π­Ρ‚ΠΎ простой, Π½ΠΎ ΠΌΠΎΡ‰Π½Ρ‹ΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ позволяСт ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π² ΠΊΠΎΠ΄Π΅ возмоТности ΠΊΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ.

Π’ этом руководствС ΠΌΡ‹ рассмотрим:

  • ΠΊΠ°ΠΊΠΈΠ΅ стратСгии ΠΊΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ доступны ΠΈ ΠΊΠ°ΠΊ ΠΈΡ… Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ΠΎΠ²;
  • Ρ‡Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅ LRU ΠΈ ΠΊΠ°ΠΊ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ этот ΠΏΠΎΠ΄Ρ…ΠΎΠ΄;
  • ΠΊΠ°ΠΊ ΠΏΠΎΠ²Ρ‹ΡΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€Π° @lru_cache;
  • ΠΊΠ°ΠΊ Ρ€Π°ΡΡˆΠΈΡ€ΠΈΡ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€Π° @lru_cache ΠΈ ΠΏΡ€Π΅ΠΊΡ€Π°Ρ‚ΠΈΡ‚ΡŒ ΠΊΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΏΠΎ истСчСнии ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ ΠΈΠ½Ρ‚Π΅Ρ€Π²Π°Π»Π° Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ.

ΠšΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π² Python: Π² Ρ‡Π΅ΠΌ польза

ΠšΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ – это ΠΌΠ΅Ρ‚ΠΎΠ΄ ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΠΈ хранСния Π΄Π°Π½Π½Ρ‹Ρ…, ΠΏΡ€ΠΈ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ с Π΄Π°Π½Π½Ρ‹ΠΌΠΈ производятся эффСктивнСС, Ρ‡Π΅ΠΌ Π² ΠΈΡ… источникС.

ΠŸΡ€Π΅Π΄ΡΡ‚Π°Π²ΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ создаСм ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ для чтСния новостСй, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π°Π³Ρ€Π΅Π³ΠΈΡ€ΡƒΠ΅Ρ‚ новости ΠΈΠ· Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… источников. ΠŸΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ пСрСмСщаСтся ΠΏΠΎ списку, ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅Ρ‚ ΡΡ‚Π°Ρ‚ΡŒΠΈ ΠΈ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Π΅Ρ‚ ΠΈΡ… Π½Π° экранС.

Как поступит ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°, Ссли Ρ‡ΠΈΡ‚Π°Ρ‚Π΅Π»ΡŒ Ρ€Π΅ΡˆΠΈΡ‚ ΡΡ€Π°Π²Π½ΠΈΡ‚ΡŒ ΠΏΠ°Ρ€Ρƒ статСй ΠΈ станСт ΠΌΠ½ΠΎΠ³ΠΎΠΊΡ€Π°Ρ‚Π½ΠΎ ΠΌΠ΅ΠΆΠ΄Ρƒ Π½ΠΈΠΌΠΈ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Ρ‚ΡŒΡΡ? Π‘Π΅Π· ΠΊΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡŽ придСтся ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ€Π°Π· ΠΏΠΎΠ»ΡƒΡ‡Π°Ρ‚ΡŒ ΠΎΠ΄Π½ΠΎ ΠΈ Ρ‚ΠΎ ΠΆΠ΅ содСрТимоС. Π’ этом случаС нСэффСктивно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΈ систСма ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ, ΠΈ сСрвСр со ΡΡ‚Π°Ρ‚ΡŒΡΠΌΠΈ, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ создаСтся Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Π°Ρ Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠ°.

Π›ΡƒΡ‡ΡˆΠΈΠΌ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΎΠΌ послС получСния ΡΡ‚Π°Ρ‚ΡŒΠΈ Π±Ρ‹Π»ΠΎ Π±Ρ‹ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚ локально. Когда ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Π² ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Ρ€Π°Π· ΠΎΡ‚ΠΊΡ€ΠΎΠ΅Ρ‚ ΡΡ‚Π°Ρ‚ΡŒΡŽ, ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ смоТСт ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΡŒ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚ ΠΈΠ· сохранСнной ΠΊΠΎΠΏΠΈΠΈ, вмСсто Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π·Π°Π½ΠΎΠ²ΠΎ Π·Π°Π³Ρ€ΡƒΠΆΠ°Ρ‚ΡŒ ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π» ΠΈΠ· источника. Π’ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΈΠΊΠ΅ этот ΠΌΠ΅Ρ‚ΠΎΠ΄ называСтся ΠΊΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ.

РСализация ΠΊΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ Π² Python посрСдством словаря

Π’ Python ΠΌΠΎΠΆΠ½ΠΎ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ. ВмСсто Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ€Π°Π· ΠΎΠ±Ρ€Π°Ρ‰Π°Ρ‚ΡŒΡΡ ΠΊ сСрвСру, ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡΡ‚ΡŒ, Π΅ΡΡ‚ΡŒ Π»ΠΈ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚ Π² кэшС, ΠΈ ΠΎΠΏΡ€Π°ΡˆΠΈΠ²Π°Ρ‚ΡŒ сСрвСр Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ссли ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π° Π½Π΅Ρ‚. Π’ качСствС ΠΊΠ»ΡŽΡ‡Π° ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ URL ΡΡ‚Π°Ρ‚ΡŒΠΈ, Π° Π² качСствС значСния – Π΅Π΅ содСрТимоС:

        import requests

link = "https://proglib.io/p/vse-chto-nuzhno-znat-o-dekoratorah-python-2020-05-09"
cache = dict()

def get_article_from_server(url):
    print("Π—Π°Π±ΠΈΡ€Π°Π΅ΠΌ ΡΡ‚Π°Ρ‚ΡŒΡŽ с сСрвСра...")
    response = requests.get(url)
    return response.text

def get_article(url):
    print("ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ ΡΡ‚Π°Ρ‚ΡŒΡŽ...")
    if url not in cache:
        cache[url] = get_article_from_server(url)

    return cache[url]

get_article(link)[:1000]
get_article(link)[:1000]
    
        ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ ΡΡ‚Π°Ρ‚ΡŒΡŽ...
Π—Π°Π±ΠΈΡ€Π°Π΅ΠΌ ΡΡ‚Π°Ρ‚ΡŒΡŽ с сСрвСра...
ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ ΡΡ‚Π°Ρ‚ΡŒΡŽ...
'\n\n\n\n<!DOCTYPE html>\n<html lang="ru" >\n\n...'
    

ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅. Для запуска этого ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° Ρƒ вас Π΄ΠΎΠ»ΠΆΠ½Π° Π±Ρ‹Ρ‚ΡŒ установлСна Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° requests:

        pip install requests
    

Π₯отя Π²Ρ‹Π·ΠΎΠ² get_article() выполняСтся Π΄Π²Π°ΠΆΠ΄Ρ‹, ΡΡ‚Π°Ρ‚ΡŒΡ с сСрвСра загруТаСтся лишь ΠΎΠ΄ΠΈΠ½ Ρ€Π°Π·. ПослС ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ доступа ΠΊ ΡΡ‚Π°Ρ‚ΡŒΠ΅ ΠΌΡ‹ ΠΏΠΎΠΌΠ΅Ρ‰Π°Π΅ΠΌ Π΅Π΅ URL ΠΈ содСрТимоС Π² ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ cache. Π’ΠΎ Π²Ρ‚ΠΎΡ€ΠΎΠΉ Ρ€Π°Π· ΠΊΠΎΠ΄ Π½Π΅ Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎΠ³ΠΎ получСния элСмСнта с сСрвСра.

Π‘Ρ‚Ρ€Π°Ρ‚Π΅Π³ΠΈΠΈ ΠΊΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ

Π’ этой простой Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΊΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ Π·Π°ΠΊΡ€Π°Π»Π°ΡΡŒ очСвидная ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°: содСрТимоС словаря Π±ΡƒΠ΄Π΅Ρ‚ Π½Π΅ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½Π½ΠΎ расти: Ρ‡Π΅ΠΌ большС статСй ΠΎΡ‚ΠΊΡ€Ρ‹Π» ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ, Ρ‚Π΅ΠΌ большС Π±Ρ‹Π»ΠΎ использовано мСста Π² памяти.

Π§Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ±ΠΎΠΉΡ‚ΠΈ эту ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ, Π½Π°ΠΌ Π½ΡƒΠΆΠ½Π° стратСгия, которая ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΡ‚ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ Ρ€Π΅ΡˆΠΈΡ‚ΡŒ, ΠΊΠ°ΠΊΠΈΠ΅ ΡΡ‚Π°Ρ‚ΡŒΠΈ ΠΏΠΎΡ€Π° ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ. БущСствуСт нСсколько Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… стратСгий, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ для удалСния элСмСнтов ΠΈΠ· кэша ΠΈ прСдотвращСния ΠΏΡ€Π΅Π²Ρ‹ΡˆΠ΅Π½ΠΈΡ Π΅Π³ΠΎ максимального Ρ€Π°Π·ΠΌΠ΅Ρ€Π°. ΠŸΡΡ‚ΡŒ самых популярных пСрСчислСны Π² Ρ‚Π°Π±Π»ΠΈΡ†Π΅.

БтратСгия ΠšΠ°ΠΊΡƒΡŽ запись удаляСм Π­Ρ‚ΠΈ записи Ρ‡Π°Ρ‰Π΅ Π΄Ρ€ΡƒΠ³ΠΈΡ… ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎ
First-In/First-Out (FIFO) Бамая старая НовыС
Last-In/First-Out (LIFO) Бамая нСдавняя Π‘Ρ‚Π°Ρ€Ρ‹Π΅
Least Recently Used (LRU) Использовалась Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ Π΄Π°Π²Π½ΠΎ НСдавно ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Π½Π½Ρ‹Π΅
Most Recently Used (MRU) Использовалась послСднСй ΠŸΡ€ΠΎΡ‡ΠΈΡ‚Π°Π½Π½Ρ‹Π΅ ΠΏΠ΅Ρ€Π²Ρ‹ΠΌΠΈ
Least Frequently Used (LFU) Использовалась Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ Ρ€Π΅Π΄ΠΊΠΎ Использовались часто

ΠŸΠΎΠ³Ρ€ΡƒΠΆΠ°Π΅ΠΌΡΡ Π² идСю LRU-ΠΊΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ

Кэш, Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ посрСдством стратСгии LRU, упорядочиваСт элСмСнты Π² порядкС ΠΈΡ… использования. ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ€Π°Π·, ΠΊΠΎΠ³Π΄Π° ΠΌΡ‹ обращаСмся ΠΊ записи, Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ LRU ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅Ρ‚ Π΅Π΅ Π² Π²Π΅Ρ€Ρ…Π½ΡŽΡŽ Ρ‡Π°ΡΡ‚ΡŒ кэша. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ ΠΌΠΎΠΆΠ΅Ρ‚ быстро ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ запись, которая дольшС всСх Π½Π΅ использовалась, ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΠ² ΠΊΠΎΠ½Π΅Ρ† списка.

На ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ рисункС ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ прСдставлСниС кэша послС Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ запросил ΡΡ‚Π°Ρ‚ΡŒΡŽ ΠΈΠ· сСти.

ΠŸΡ€ΠΎΡ†Π΅ΡΡ заполнСния LRU-кэша, шаг 1
ΠŸΡ€ΠΎΡ†Π΅ΡΡ заполнСния LRU-кэша, шаг 1

Π‘Ρ‚Π°Ρ‚ΡŒΡ сохраняСтся Π² послСднСм слотС кэша ΠΏΠ΅Ρ€Π΅Π΄ Ρ‚Π΅ΠΌ, ΠΊΠ°ΠΊ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π° ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŽ. На ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ рисункС ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ, Ρ‡Ρ‚ΠΎ происходит, ΠΊΠΎΠ³Π΄Π° ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°Π΅Ρ‚ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΡƒΡŽ ΡΡ‚Π°Ρ‚ΡŒΡŽ.

ΠŸΡ€ΠΎΡ†Π΅ΡΡ заполнСния LRU-кэша, шаг 2
ΠŸΡ€ΠΎΡ†Π΅ΡΡ заполнСния LRU-кэша, шаг 2

Вторая ΡΡ‚Π°Ρ‚ΡŒΡ Π·Π°Π½ΠΈΠΌΠ°Π΅Ρ‚ послСдний слот, пСрСмСщая ΠΏΠ΅Ρ€Π²ΡƒΡŽ ΡΡ‚Π°Ρ‚ΡŒΡŽ Π²Π½ΠΈΠ· ΠΏΠΎ списку.

БтратСгия LRU ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π΅Ρ‚: Ρ‡Π΅ΠΌ ΠΏΠΎΠ·ΠΆΠ΅ использовался ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, Ρ‚Π΅ΠΌ большС Π²Π΅Ρ€ΠΎΡΡ‚Π½ΠΎΡΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΎΠ½ понадобится Π² Π±ΡƒΠ΄ΡƒΡ‰Π΅ΠΌ. Алгоритм сохраняСт Ρ‚Π°ΠΊΠΎΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π² кэшС Π² Ρ‚Π΅Ρ‡Π΅Π½ΠΈΠ΅ максимально Π΄Π»ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ.

ЗаглядываСм Π·Π° кулисы кэша LRU

Один ΠΈΠ· способов Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ кэш LRU Π² Python – ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠΎΠΌΠ±ΠΈΠ½Π°Ρ†ΠΈΡŽ двусвязного списка ΠΈ Ρ…Π΅Ρˆ-Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹. Π“ΠΎΠ»ΠΎΠ²Π½ΠΎΠΉ элСмСнт двусвязного списка ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ Π½Π° послСднюю Π·Π°ΠΏΡ€ΠΎΡˆΠ΅Π½Π½ΡƒΡŽ запись, Π° хвостовой – Π½Π° Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ Π΄Π°Π²Π½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Π²ΡˆΡƒΡŽΡΡ.

На рисункС Π½ΠΈΠΆΠ΅ ΠΏΠΎΠΊΠ°Π·Π°Π½Π° возмоТная структура Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ кэша LRU.

Π‘Ρ…Π΅ΠΌΠ° Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΊΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ
Π‘Ρ…Π΅ΠΌΠ° Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΊΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ

Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ Ρ…Π΅Ρˆ-Ρ‚Π°Π±Π»ΠΈΡ†Ρƒ, ΠΌΡ‹ обСспСчиваСм доступ ΠΊ ΠΊΠ°ΠΆΠ΄ΠΎΠΌΡƒ элСмСнту Π² кэшС, сопоставляя ΠΊΠ°ΠΆΠ΄ΡƒΡŽ запись с ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹ΠΌ мСстом Π² двусвязном спискС. ΠŸΡ€ΠΈ этом доступ ΠΊ Π½Π΅Π΄Π°Π²Π½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Π²ΡˆΠ΅ΠΌΡƒΡΡ элСмСнту ΠΈ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ кэша – это ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ, выполняСмыС Π·Π° константноС врСмя (Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ с Π²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ ΡΠ»ΠΎΠΆΠ½ΠΎΡΡ‚ΡŒΡŽ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠ° 𝑂(1).

ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅
ΠŸΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ Π²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ слоТности Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ Python Ρ€Π°ΡΡΠΌΠ°Ρ‚Ρ€ΠΈΠ²Π°Π»ΠΈΡΡŒ Π½Π° proglib Π² ΡΡ‚Π°Ρ‚ΡŒΠ΅ Β«Π‘Π»ΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠΎΠ² ΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ PythonΒ».

Начиная с вСрсии 3.2, для Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ стратСгии LRU Python Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ @lru_cache.

ИспользованиС @lru_cache для Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ кэша LRU Π² Python

Π”Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ @lru_cache Π·Π° кулисами ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ. Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ выполнСния Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΊΡΡˆΠΈΡ€ΡƒΠ΅Ρ‚ΡΡ ΠΏΠΎΠ΄ ΠΊΠ»ΡŽΡ‡ΠΎΠΌ, ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΌ Π²Ρ‹Π·ΠΎΠ²Ρƒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈ прСдоставлСнным Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π°ΠΌ. Π’ΠΎ Π΅ΡΡ‚ΡŒ Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ Ρ€Π°Π±ΠΎΡ‚Π°Π», Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ Ρ…Π΅ΡˆΠΈΡ€ΡƒΠ΅ΠΌΡ‹ΠΌΠΈ.

НаглядноС прСдставлСниС Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠ°: ΠΏΠ΅Ρ€Π΅ΠΏΡ€Ρ‹Π³ΠΈΠ²Π°Π΅ΠΌ ΡΡ‚ΡƒΠΏΠ΅Π½ΡŒΠΊΠΈ

ΠŸΡ€Π΅Π΄ΡΡ‚Π°Π²ΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ Ρ…ΠΎΡ‚ΠΈΠΌ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ число способов, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌΠΈ ΠΌΠΎΠΆΠ΅ΠΌ Π΄ΠΎΡΡ‚ΠΈΡ‡ΡŒ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠΉ ΡΡ‚ΡƒΠΏΠ΅Π½ΡŒΠΊΠΈ Π½Π° лСстницС. Бколько Π΅ΡΡ‚ΡŒ способов, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π΄ΠΎΠ±Ρ€Π°Ρ‚ΡŒΡΡ Π΄ΠΎ Ρ‡Π΅Ρ‚Π²Π΅Ρ€Ρ‚ΠΎΠΉ ΡΡ‚ΡƒΠΏΠ΅Π½ΡŒΠΊΠΈ, Ссли ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠ΅Ρ€Π΅ΡΡ‚ΡƒΠΏΠΈΡ‚ΡŒ-ΠΏΠ΅Ρ€Π΅ΠΏΡ€Ρ‹Π³Π½ΡƒΡ‚ΡŒ 1, 2, 3 (Π½ΠΎ Π½Π΅ Π±ΠΎΠ»Π΅Π΅) ΡΡ‚ΡƒΠΏΠ΅Π½ΡŒΠΊΠΈ? На рисункС Π½ΠΈΠΆΠ΅ прСдставлСны ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠ΅ ΠΊΠΎΠΌΠ±ΠΈΠ½Π°Ρ†ΠΈΠΈ.

🧩 ΠšΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π² Python: Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ LRU

Под ΠΊΠ°ΠΆΠ΄Ρ‹ΠΌ ΠΈΠ· рисунков ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ ΠΏΡƒΡ‚ΡŒ с ΡƒΠΊΠ°Π·Π°Π½ΠΈΠ΅ΠΌ числа ступСнСк, ΠΏΡ€Π΅ΠΎΠ΄ΠΎΠ»Π΅Π½Π½Ρ‹Ρ… Π·Π° ΠΎΠ΄ΠΈΠ½ ΠΏΡ€Ρ‹ΠΆΠΎΠΊ. ΠŸΡ€ΠΈ этом количСство способов достиТСния Ρ‡Π΅Ρ‚Π²Π΅Ρ€Ρ‚ΠΎΠΉ ΡΡ‚ΡƒΠΏΠ΅Π½ΡŒΠΊΠΈ Ρ€Π°Π²Π½ΠΎ ΠΎΠ±Ρ‰Π΅ΠΌΡƒ числу способов, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌΠΈ ΠΌΠΎΠΆΠ½ΠΎ Π΄ΠΎΠ±Ρ€Π°Ρ‚ΡŒΡΡ Π΄ΠΎ Ρ‚Ρ€Π΅Ρ‚ΡŒΠ΅ΠΉ, Π²Ρ‚ΠΎΡ€ΠΎΠΉ ΠΈ ΠΏΠ΅Ρ€Π²ΠΎΠΉ ступСнСк:

🧩 ΠšΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π² Python: Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ LRU

ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ΡΡ, Ρ‡Ρ‚ΠΎ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ Π·Π°Π΄Π°Ρ‡ΠΈ ΠΌΠΎΠΆΠ½ΠΎ Ρ€Π°Π·Π»ΠΎΠΆΠΈΡ‚ΡŒ Π½Π° Π±ΠΎΠ»Π΅Π΅ ΠΌΠ΅Π»ΠΊΠΈΠ΅ ΠΏΠΎΠ΄Π·Π°Π΄Π°Ρ‡ΠΈ. Π§Ρ‚ΠΎΠ±Ρ‹ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ ΠΏΡƒΡ‚ΠΈ ΠΊ Ρ‡Π΅Ρ‚Π²Π΅Ρ€Ρ‚ΠΎΠΉ ΡΡ‚ΡƒΠΏΠ΅Π½ΡŒΠΊΠ΅, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠ»ΠΎΠΆΠΈΡ‚ΡŒ Ρ‡Π΅Ρ‚Ρ‹Ρ€Π΅ способа достиТСния Ρ‚Ρ€Π΅Ρ‚ΡŒΠ΅ΠΉ ΡΡ‚ΡƒΠΏΠ΅Π½ΡŒΠΊΠΈ, Π΄Π²Π° способа достиТСния Π²Ρ‚ΠΎΡ€ΠΎΠΉ ΡΡ‚ΡƒΠΏΠ΅Π½ΡŒΠΊΠΈ ΠΈ СдинствСнный способ для ΠΏΠ΅Ρ€Π²ΠΎΠΉ. Π’ΠΎ Π΅ΡΡ‚ΡŒ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ рСкурсивный ΠΏΠΎΠ΄Ρ…ΠΎΠ΄.

ОпишСм ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎ рСкурсивноС Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ Π² точности, ΠΊΠ°ΠΊ ΠΌΡ‹ Π΅Π³ΠΎ сСйчас Π²ΠΈΠ΄ΠΈΠΌ:

        def steps_to(stair):
    if stair == 1:
        # Π”ΠΎ ΠΏΠ΅Ρ€Π²ΠΎΠΉ ΡΡ‚ΡƒΠΏΠ΅Π½ΡŒΠΊΠΈ ΠΌΠΎΠΆΠ½ΠΎ Π΄ΠΎΠ±Ρ€Π°Ρ‚ΡŒΡΡ с ΠΏΠΎΠ»Π° 
        # СдинствСнным ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ
        return 1
    elif stair == 2:
        # Π’Ρ‚ΠΎΡ€ΠΎΠΉ ΡΡ‚ΡƒΠΏΠ΅Π½ΡŒΠΊΠΈ ΠΌΠΎΠΆΠ½ΠΎ Π΄ΠΎΡΡ‚ΠΈΠ½Π³ΡƒΡ‚ΡŒ,
        # ступая ΠΏΠΎ ΠΎΠ΄Π½ΠΎΠΉ Π·Π° Ρ€Π°Π· ΠΈΠ»ΠΈ ΠΏΡ€Π΅ΠΎΠ΄ΠΎΠ»Π΅Π² сразу Π΄Π²Π΅
        return 2
    elif stair == 3:
        # Π§Ρ‚ΠΎΠ±Ρ‹ Π΄ΠΎΠ±Ρ€Π°Ρ‚ΡŒΡΡ Π΄ΠΎ Ρ‚Ρ€Π΅Ρ‚ΡŒΠ΅ΠΉ ΡΡ‚ΡƒΠΏΠ΅Π½ΡŒΠΊΠΈ:
        # 1. ΠŸΠ΅Ρ€Π΅ΠΏΡ€Ρ‹Π³Π½ΡƒΡ‚ΡŒ сразу Π΄ΠΎ Ρ‚Ρ€Π΅Ρ‚ΡŒΠ΅ΠΉ
        # 2. ΠŸΠ΅Ρ€Π΅ΠΏΡ€Ρ‹Π³Π½ΡƒΡ‚ΡŒ Π΄Π²Π΅, ΠΏΠΎΡ‚ΠΎΠΌ ΠΎΠ΄Π½Ρƒ
        # 3. ΠŸΠ΅Ρ€Π΅ΠΏΡ€Ρ‹Π³Π½ΡƒΡ‚ΡŒ ΠΎΠ΄Π½Ρƒ ΠΏΠΎΡ‚ΠΎΠΌ Π΄Π²Π΅
        # 4. По ΠΎΠ΄Π½ΠΎΠΉ Π·Π° Ρ€Π°Π·
        return 4
    else:
        # ВсС ΠΏΡ€ΠΎΠΌΠ΅ΠΆΡƒΡ‚ΠΎΡ‡Π½Ρ‹Π΅ шаги это Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅
        # Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Ρ‹ ΠΏΡ€Ρ‹ΠΆΠΊΠΎΠ² Ρ‡Π΅Ρ€Π΅Π· 1, 2 ΠΈΠ»ΠΈ 3 ΡΡ‚ΡƒΠΏΠ΅Π½ΡŒΠΊΠΈ,
        # Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ ΠΎΠ±Ρ‰Π΅Π΅ число Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ΠΎΠ² - это сумма
        # Ρ‚Π°ΠΊΠΈΡ… ΠΊΠΎΠΌΠ±ΠΈΠ½Π°Ρ†ΠΈΠΉ
        return (
            steps_to(stair - 3)
            + steps_to(stair - 2)
            + steps_to(stair - 1)
        )
    
        >>> print(steps_to(4))
7
    

Код Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ для 4 ступСнСк. Π”Π°Π²Π°ΠΉΡ‚Π΅ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΠΌ, ΠΊΠ°ΠΊ ΠΎΠ½ подсчитаСт число Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ΠΎΠ² для лСстницы ΠΈΠ· 30 ступСнСк.

        >>> steps_to(30)
53798080
    

ΠŸΠΎΠ»ΡƒΡ‡ΠΈΠ»ΠΎΡΡŒ ΡΠ²Ρ‹ΡˆΠ΅ 53 ΠΌΠ»Π½. ΠΊΠΎΠΌΠ±ΠΈΠ½Π°Ρ†ΠΈΠΉ. Однако ΠΊΠΎΠ³Π΄Π° ΠΌΡ‹ искали Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ для Ρ‚Ρ€ΠΈΠ΄Ρ†Π°Ρ‚ΠΎΠΉ ΡΡ‚ΡƒΠΏΠ΅Π½ΡŒΠΊΠΈ, сцСнарий ΠΌΠΎΠ³ Π΄Π»ΠΈΡ‚ΡŒΡΡ довольно Π΄ΠΎΠ»Π³ΠΎ.

ЗасСкаСм врСмя выполнСния ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π°

Π˜Π·ΠΌΠ΅Ρ€ΠΈΠΌ, ΠΊΠ°ΠΊ Π΄ΠΎΠ»Π³ΠΎ длится Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΊΠΎΠ΄Π°.

ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅
О Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π°Ρ… Ρ€Π°Π±ΠΎΡ‚Ρ‹ со Π²Ρ€Π΅ΠΌΠ΅Π½Π΅ΠΌ Π² Python Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ Π² ΠΏΡƒΠ±Π»ΠΈΠΊΠ°Ρ†ΠΈΠΈ «Назад Π² Π±ΡƒΠ΄ΡƒΡ‰Π΅Π΅: практичСскоС руководство ΠΏΠΎ ΠΏΡƒΡ‚Π΅ΡˆΠ΅ΡΡ‚Π²ΠΈΡŽ Π²ΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ с PythonΒ». Π­Ρ‚Π° публикация Ρ‚Π°ΠΊΠΆΠ΅ Π°Π΄Π°ΠΏΡ‚ΠΈΡ€ΠΎΠ²Π°Π½Π° Π² Π²ΠΈΠ΄Π΅ Π±Π»ΠΎΠΊΠ½ΠΎΡ‚Π° Jupyter.

Для этого ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ Python timeit ΠΈΠ»ΠΈ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΡƒΡŽ ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ Π² Π±Π»ΠΎΠΊΠ½ΠΎΡ‚Π΅ Jupyter.

        %%timeit
>>> steps_to(30)
53798080

4.53 s Β± 67.3 ms per loop (mean Β± std. dev. of 7 runs, 1 loop each)
    

ΠšΠΎΠ»ΠΈΡ‡Π΅ΡΡ‚Π²ΠΎ сСкунд зависит ΠΎΡ‚ характСристик ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΠΎΠ³ΠΎ ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€Π°. Π’ ΠΌΠΎΠ΅ΠΉ систСмС расчСт занял 3 сСкунды, Ρ‡Ρ‚ΠΎ довольно ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎ для всСго Ρ‚Ρ€ΠΈΠ΄Ρ†Π°Ρ‚ΠΈ ступСнСк. Π­Ρ‚ΠΎ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ½ΠΎ Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΡƒΠ»ΡƒΡ‡ΡˆΠΈΡ‚ΡŒ c ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΌΠ΅ΠΌΠΎΠΈΠ·Π°Ρ†ΠΈΠΈ.

ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅
Один ΠΈΠ· ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΎΠ² ΠΌΠ΅ΠΌΠΎΠΈΠ·Π°Ρ†ΠΈΠΈ рассматривался Π² ΡΡ‚Π°Ρ‚ΡŒΠ΅Β«Python ΠΈ динамичСскоС ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ Π·Π°Π΄Π°Ρ‡ΠΈ ΠΎ Ρ€ΡŽΠΊΠ·Π°ΠΊΠ΅Β».

ИспользованиС ΠΌΠ΅ΠΌΠΎΠΈΠ·Π°Ρ†ΠΈΠΈ для ΡƒΠ»ΡƒΡ‡ΡˆΠ΅Π½ΠΈΡ Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ

Наша рСкурсивная рСализация Ρ€Π΅ΡˆΠ°Π΅Ρ‚ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ, разбивая Π΅Π΅ Π½Π° Π±ΠΎΠ»Π΅Π΅ ΠΌΠ΅Π»ΠΊΠΈΠ΅ шаги, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π΄ΠΎΠΏΠΎΠ»Π½ΡΡŽΡ‚ Π΄Ρ€ΡƒΠ³ Π΄Ρ€ΡƒΠ³Π°. На ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ рисункС ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π΄Π΅Ρ€Π΅Π²ΠΎ для сСми ступСнСк, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΡƒΠ·Π΅Π» прСдставляСт ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹ΠΉ Π²Ρ‹Π·ΠΎΠ² steps_to():

Π”Π΅Ρ€Π΅Π²ΠΎ Π²Ρ‹Π·ΠΎΠ²ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ step_to()
Π”Π΅Ρ€Π΅Π²ΠΎ Π²Ρ‹Π·ΠΎΠ²ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ step_to()

МоТно Π·Π°ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΡƒ приходится Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ steps_to() с ΠΎΠ΄Π½ΠΈΠΌ ΠΈ Ρ‚Π΅ΠΌ ΠΆΠ΅ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠΌ нСсколько Ρ€Π°Π·. НапримСр, steps_to(5) вычисляСтся Π΄Π²Π° Ρ€Π°Π·Π°, steps_to(4) – Ρ‡Π΅Ρ‚Ρ‹Ρ€Π΅ Ρ€Π°Π·Π°, steps_to(3) – сСмь Ρ€Π°Π· ΠΈ Ρ‚. Π΄. Π’Ρ‹Π·ΠΎΠ² ΠΎΠ΄Π½ΠΎΠΉ ΠΈ Ρ‚ΠΎΠΉ ΠΆΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ нСсколько Ρ€Π°Π· запускаСт вычислСния, Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π½Π΅Ρ‚ нСобходимости – Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ всСгда ΠΎΠ΄ΠΈΠ½ ΠΈ Ρ‚ΠΎΡ‚ ΠΆΠ΅.

Π§Ρ‚ΠΎΠ±Ρ‹ Ρ€Π΅ΡˆΠΈΡ‚ΡŒ эту ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΌΠ΅ΠΌΠΎΠΈΠ·Π°Ρ†ΠΈΡŽ: ΠΌΡ‹ сохраняСм Π² памяти Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚, ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹ΠΉ для ΠΎΠ΄Π½ΠΈΡ… ΠΈ Ρ‚Π΅Ρ… ΠΆΠ΅ Π²Ρ…ΠΎΠ΄Π½Ρ‹Ρ… Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ ΠΈ Π·Π°Ρ‚Π΅ΠΌ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌ ΠΏΡ€ΠΈ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½ΠΎΠΌ запросС. ΠŸΡ€Π΅ΠΊΡ€Π°ΡΠ½Π°Ρ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΡ‚ΡŒ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ @lru_cache!

ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅
Если Π²Ρ‹ Π½Π΅Π·Π½Π°ΠΊΠΎΠΌΡ‹ с ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ†ΠΈΠ΅ΠΉ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ΠΎΠ², Π½ΠΎ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ Π³Π»ΡƒΠ±ΠΆΠ΅ Ρ€Π°Π·ΠΎΠ±Ρ€Π°Ρ‚ΡŒΡΡ Π² вопросС, просто ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°ΠΉΡ‚Π΅ матСриал«Всё, Ρ‡Ρ‚ΠΎ Π½ΡƒΠΆΠ½ΠΎ Π·Π½Π°Ρ‚ΡŒ ΠΎ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€Π°Ρ… PythonΒ» (ΠΎΠ½Π° Ρ‚Π°ΠΊΠΆΠ΅ Π°Π΄Π°ΠΏΡ‚ΠΈΡ€ΠΎΠ²Π°Π½Π° Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅JupyterΠΈ Colab). Для Π½Π°ΡˆΠΈΡ… Π·Π°Π΄Π°Ρ‡ достаточно Π·Π½Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ это Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ-ΠΎΠ±Π΅Ρ€Ρ‚ΠΊΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ ΠΌΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ ΠΈ классов. Π§Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΡ‚ΡŒ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€, достаточно ΠΎΠ±ΡŠΡΠ²ΠΈΡ‚ΡŒ Π΅Π³ΠΎ ΠΏΠ΅Ρ€Π΅Π΄ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ.

Π˜ΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΠ΅ΠΌ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ ΠΈΠ· модуля functools ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΠΌ ΠΊ основной Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ.

        from functools import lru_cache

@lru_cache()
def steps_to(stair):
    if stair == 1:
        return 1
    elif stair == 2:
        return 2
    elif stair == 3:
        return 4
    else:
        return (steps_to(stair - 3)
                + steps_to(stair - 2)
                + steps_to(stair - 1))
    
ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅
Π’ Python 3.8 ΠΈ Π²Ρ‹ΡˆΠ΅, Ссли Π²Ρ‹ Π½Π΅ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚Π΅ Π½ΠΈΠΊΠ°ΠΊΠΈΡ… ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ², ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ @lru_cache Π±Π΅Π· скобок. Π’ Π±ΠΎΠ»Π΅Π΅ Ρ€Π°Π½Π½ΠΈΡ… вСрсиях Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΊΡ€ΡƒΠ³Π»Ρ‹Π΅ скобки: @lru_cache().
        %%timeit
>>> steps_to(30)
53798080

82.7 ns Β± 3.4 ns per loop (mean Β± std. dev. of 7 runs, 10000000 loops each)
    

ΠžΡ‚ Π΅Π΄ΠΈΠ½ΠΈΡ† сСкунд ΠΊ дСсяткам наносСкунд – ΠΏΠΎΡ‚Ρ€ΡΡΠ°ΡŽΡ‰Π΅Π΅ ΡƒΠ»ΡƒΡ‡ΡˆΠ΅Π½ΠΈΠ΅, обязанноС Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎ Π·Π° кулисами Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ @lru_cache сохраняСт Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ Π²Ρ‹Π·ΠΎΠ²Π° steps_to() для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½ΠΎΠ³ΠΎ Π²Ρ…ΠΎΠ΄Π½ΠΎΠ³ΠΎ значСния.

Π”Ρ€ΡƒΠ³ΠΈΠ΅ возмоТности @lru_cache

ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΠ² Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ @lru_cache, ΠΌΡ‹ сохраняСм ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Π²Ρ‹Π·ΠΎΠ² ΠΈ ΠΎΡ‚Π²Π΅Ρ‚ Π² памяти для ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π³ΠΎ доступа, Ссли ΠΎΠ½ΠΈ ΠΏΠΎΡ‚Ρ€Π΅Π±ΡƒΡŽΡ‚ΡΡ снова. Но сколько Ρ‚Π°ΠΊΠΈΡ… ΠΊΠΎΠΌΠ±ΠΈΠ½Π°Ρ†ΠΈΠΉ ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠΎΡ…Ρ€Π°Π½ΠΈΡ‚ΡŒ, ΠΏΠΎΠΊΠ° Π½Π΅ иссякнСт ΠΏΠ°ΠΌΡΡ‚ΡŒ?

Π£ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€Π° @lru_cache Π΅ΡΡ‚ΡŒ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ maxsize, ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‰ΠΈΠΉ максимальноС количСство записСй Π΄ΠΎ Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ кэш Π½Π°Ρ‡Π½Π΅Ρ‚ ΡƒΠ΄Π°Π»ΡΡ‚ΡŒ старыС элСмСнты. По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ maxsize Ρ€Π°Π²Π΅Π½ 128. Если ΠΌΡ‹ присвоим maxsize Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ None, Ρ‚ΠΎ кэш Π±ΡƒΠ΄Π΅Ρ‚ расти Π±Π΅Π· всякого удалСния записСй. Π­Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ ΡΡ‚Π°Ρ‚ΡŒ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠΎΠΉ, Ссли ΠΌΡ‹ Ρ…Ρ€Π°Π½ΠΈΠΌ Π² памяти слишком ΠΌΠ½ΠΎΠ³ΠΎ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… Π²Ρ‹Π·ΠΎΠ²ΠΎΠ².

ΠŸΡ€ΠΈΠΌΠ΅Π½ΠΈΠΌ @lru_cache с использованиСм Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π° maxsize ΠΈ Π΄ΠΎΠ±Π°Π²ΠΈΠΌ Π²Ρ‹Π·ΠΎΠ² ΠΌΠ΅Ρ‚ΠΎΠ΄Π° cache_info():

        @lru_cache(maxsize=16)
def steps_to(stair):
    if stair == 1:
        return 1
    elif stair == 2:
        return 2
    elif stair == 3:
        return 4
    else:
        return (steps_to(stair - 3)
                + steps_to(stair - 2)
                + steps_to(stair - 1))
  
    
        >>> steps_to(30)
53798080
>>> steps_to.cache_info()
CacheInfo(hits=52, misses=30, maxsize=16, currsize=16)
    

ΠœΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡƒΡŽ cache_info(), Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ½ΡΡ‚ΡŒ, ΠΊΠ°ΠΊ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ кэш, ΠΈ Π½Π°ΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ Π΅Π³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π½Π°ΠΉΡ‚ΠΈ подходящий баланс ΠΌΠ΅ΠΆΠ΄Ρƒ ΡΠΊΠΎΡ€ΠΎΡΡ‚ΡŒΡŽ Ρ€Π°Π±ΠΎΡ‚Ρ‹ ΠΈ объСмом памяти:

  • hits=52 – количСство Π²Ρ‹Π·ΠΎΠ²ΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ @lru_cache Π²Π΅Ρ€Π½ΡƒΠ» нСпосрСдствСнно ΠΈΠ· памяти, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΠ½ΠΈ присутствовали Π² кэшС;
  • misses=30 – количСство Π²Ρ‹Π·ΠΎΠ²ΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ взяты Π½Π΅ ΠΈΠ· памяти, Π° Π±Ρ‹Π»ΠΈ вычислСны (Π² случаС нашСй Π·Π°Π΄Π°Ρ‡ΠΈ это каТдая новая ΡΡ‚ΡƒΠΏΠ΅Π½ΡŒ);
  • maxsize=16 – это Ρ€Π°Π·ΠΌΠ΅Ρ€ кэша, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΡ‹ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΠ»ΠΈ, ΠΏΠ΅Ρ€Π΅Π΄Π°Π² Π΅Π³ΠΎ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€Ρƒ;
  • currsize=16 – Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ Ρ€Π°Π·ΠΌΠ΅Ρ€ кэша, Π² этом случаС кэш Π·Π°ΠΏΠΎΠ»Π½Π΅Π½.

Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ срока дСйствия кэша

ΠŸΠ΅Ρ€Π΅ΠΉΠ΄Π΅ΠΌ ΠΎΡ‚ ΡƒΡ‡Π΅Π±Π½ΠΎΠ³ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° ΠΊ Π±ΠΎΠ»Π΅Π΅ рСалистичному. ΠŸΡ€Π΅Π΄ΡΡ‚Π°Π²ΡŒΡ‚Π΅, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ Ρ…ΠΎΡ‚ΠΈΠΌ ΠΎΡ‚ΡΠ»Π΅ΠΆΠΈΠ²Π°Ρ‚ΡŒ появлСниС Π½Π° рСсурсС Real Python Π½ΠΎΠ²Ρ‹Ρ… статСй, содСрТащих Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ΅ слово python – Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ΡŒ Π½Π°Π·Π²Π°Π½ΠΈΠ΅, ΡΠΊΠ°Ρ‡ΠΈΠ²Π°Ρ‚ΡŒ ΡΡ‚Π°Ρ‚ΡŒΡŽ ΠΈ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Ρ‚ΡŒ Π΅Π΅ объСм (число символов).

Real Python прСдоставляСт ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» Atom, Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΡƒ feedparser для Π°Π½Π°Π»ΠΈΠ·Π° ΠΊΠ°Π½Π°Π»Π° ΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΡƒ requests для Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ содСрТимого ΡΡ‚Π°Ρ‚ΡŒΠΈ, ΠΊΠ°ΠΊ ΠΌΡ‹ это Π΄Π΅Π»Π°Π»ΠΈ Ρ€Π°Π½ΡŒΡˆΠ΅.

        import feedparser   # pip install feedparser
import requests
import ssl
import time

if hasattr(ssl, "_create_unverified_context"):
    ssl._create_default_https_context = ssl._create_unverified_context

def get_article_from_server(url):
    print("ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΡΡ‚Π°Ρ‚ΡŒΠΈ с сСрвСра...")
    response = requests.get(url)
    return response.text

def monitor(url):
    maxlen = 45
    while True:
        try:
            print("\nΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠΌ Π»Π΅Π½Ρ‚Ρƒ...")
            feed = feedparser.parse(url)

            for entry in feed.entries[:5]:
                if "python" in entry.title.lower():
                    truncated_title = (
                        entry.title[:maxlen] + "..."
                        if len(entry.title) > maxlen
                        else entry.title
                    )
                    print(
                        "Π‘ΠΎΠ²ΠΏΠ°Π΄Π΅Π½ΠΈΠ΅:",
                        truncated_title,
                        len(get_article_from_server(entry.link)),
                    )

            time.sleep(5)
        except KeyboardInterrupt:
            break
    

Π‘ΠΊΡ€ΠΈΠΏΡ‚ Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ Π½Π΅ΠΏΡ€Π΅Ρ€Ρ‹Π²Π½ΠΎ, ΠΏΠΎΠΊΠ° ΠΌΡ‹ Π½Π΅ остановим Π΅Π³ΠΎ, Π½Π°ΠΆΠ°Π² [Ctrl + C] Π² ΠΎΠΊΠ½Π΅ Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π»Π° (ΠΈΠ»ΠΈ Π½Π΅ ΠΏΡ€Π΅Ρ€Π²Π΅ΠΌ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Π² Jupyter-Π±Π»ΠΎΠΊΠ½ΠΎΡ‚Π΅).

        >>> monitor("https://realpython.com/atom.xml")

ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠΌ Π»Π΅Π½Ρ‚Ρƒ...
ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΡΡ‚Π°Ρ‚ΡŒΠΈ с сСрвСра...
Π‘ΠΎΠ²ΠΏΠ°Π΄Π΅Π½ΠΈΠ΅: The Real Python Podcast – Episode #35: Securi... 28704
ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΡΡ‚Π°Ρ‚ΡŒΠΈ с сСрвСра...
Π‘ΠΎΠ²ΠΏΠ°Π΄Π΅Π½ΠΈΠ΅: PyPy: Faster Python With Minimal Effort 67387
ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΡΡ‚Π°Ρ‚ΡŒΠΈ с сСрвСра...
Π‘ΠΎΠ²ΠΏΠ°Π΄Π΅Π½ΠΈΠ΅: Handling Missing Keys With the Python default... 33224
ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΡΡ‚Π°Ρ‚ΡŒΠΈ с сСрвСра...
Π‘ΠΎΠ²ΠΏΠ°Π΄Π΅Π½ΠΈΠ΅: Use Sentiment Analysis With Python to Classif... 158401
ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΡΡ‚Π°Ρ‚ΡŒΠΈ с сСрвСра...
Π‘ΠΎΠ²ΠΏΠ°Π΄Π΅Π½ΠΈΠ΅: The Real Python Podcast – Episode #34: The Py... 29576

ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠΌ Π»Π΅Π½Ρ‚Ρƒ...
ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΡΡ‚Π°Ρ‚ΡŒΠΈ с сСрвСра...
Π‘ΠΎΠ²ΠΏΠ°Π΄Π΅Π½ΠΈΠ΅: The Real Python Podcast – Episode #35: Securi... 28704
ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΡΡ‚Π°Ρ‚ΡŒΠΈ с сСрвСра...
Π‘ΠΎΠ²ΠΏΠ°Π΄Π΅Π½ΠΈΠ΅: PyPy: Faster Python With Minimal Effort 67389
ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΡΡ‚Π°Ρ‚ΡŒΠΈ с сСрвСра...
Π‘ΠΎΠ²ΠΏΠ°Π΄Π΅Π½ΠΈΠ΅: Handling Missing Keys With the Python default... 33224
ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΡΡ‚Π°Ρ‚ΡŒΠΈ с сСрвСра...
Π‘ΠΎΠ²ΠΏΠ°Π΄Π΅Π½ΠΈΠ΅: Use Sentiment Analysis With Python to Classif... 158400
ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΡΡ‚Π°Ρ‚ΡŒΠΈ с сСрвСра...
Π‘ΠΎΠ²ΠΏΠ°Π΄Π΅Π½ΠΈΠ΅: The Real Python Podcast – Episode #34: The Py... 29576
    

Код Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅Ρ‚ ΠΈ Π°Π½Π°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅Ρ‚ xml-Ρ„Π°ΠΉΠ» ΠΈΠ· RealPython. Π”Π°Π»Π΅Π΅ Ρ†ΠΈΠΊΠ» ΠΏΠ΅Ρ€Π΅Π±ΠΈΡ€Π°Π΅Ρ‚ ΠΏΠ΅Ρ€Π²Ρ‹Π΅ ΠΏΡΡ‚ΡŒ записСй Π² спискС. Если слово python являСтся Ρ‡Π°ΡΡ‚ΡŒΡŽ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ°, ΠΊΠΎΠ΄ ΠΏΠ΅Ρ‡Π°Ρ‚Π°Π΅Ρ‚ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ ΠΈ Π΄Π»ΠΈΠ½Ρƒ ΡΡ‚Π°Ρ‚ΡŒΠΈ. Π—Π°Ρ‚Π΅ΠΌ ΠΊΠΎΠ΄ «засыпаСт» Π½Π° 5 сСкунд, послС Ρ‡Π΅Π³ΠΎ вновь запускаСтся ΠΌΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΈΠ½Π³.

ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ€Π°Π·, ΠΊΠΎΠ³Π΄Π° сцСнарий Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅Ρ‚ ΡΡ‚Π°Ρ‚ΡŒΡŽ, Π² консоль выводится сообщСниС Β«ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΡΡ‚Π°Ρ‚ΡŒΠΈ с сСрвСра...Β». Если ΠΌΡ‹ ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΠΌ скрипту Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ достаточно Π΄ΠΎΠ»Π³ΠΎ, ΠΌΡ‹ ΡƒΠ²ΠΈΠ΄ΠΈΠΌ, Ρ‡Ρ‚ΠΎ это сообщСниС появляСтся ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎ Π΄Π°ΠΆΠ΅ ΠΏΡ€ΠΈ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠ΅ Ρ‚ΠΎΠΉ ΠΆΠ΅ ссылки.

ΠœΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ @lru_cache, ΠΎΠ΄Π½Π°ΠΊΠΎ содСрТаниС ΡΡ‚Π°Ρ‚ΡŒΠΈ со Π²Ρ€Π΅ΠΌΠ΅Π½Π΅ΠΌ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒΡΡ. ΠŸΡ€ΠΈ ΠΏΠ΅Ρ€Π²ΠΎΠΉ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠ΅ ΡΡ‚Π°Ρ‚ΡŒΠΈ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ сохранит Π΅Π΅ содСрТимоС ΠΈ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ€Π°Π· Π±ΡƒΠ΄Π΅Ρ‚ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Ρ‚ΡŒ ΠΎΠ΄Π½ΠΈ ΠΈ Ρ‚Π΅ ΠΆΠ΅ Π΄Π°Π½Π½Ρ‹Π΅. Если сообщСниС ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΎ, Ρ‚ΠΎ сцСнарий ΠΌΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΈΠ½Π³Π° Π½ΠΈΠΊΠΎΠ³Π΄Π° ΠΎΠ± этом Π½Π΅ ΡƒΠ·Π½Π°Π΅Ρ‚. Π§Ρ‚ΠΎΠ±Ρ‹ Ρ€Π΅ΡˆΠΈΡ‚ΡŒ эту ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ, ΠΌΡ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ срок хранСния записСй Π² кэшС.

ΠšΡ€ΠΈΡ‚Π΅Ρ€ΠΈΠΈ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ записСй ΠΈΠ· кэша

ΠœΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠΏΠΈΡΠ°Π½Π½ΡƒΡŽ идСю Π² Π½ΠΎΠ²ΠΎΠΌ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€Π΅, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Ρ€Π°ΡΡˆΠΈΡ€ΡΠ΅Ρ‚ @lru_cache. Кэш Π΄ΠΎΠ»ΠΆΠ΅Π½ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Ρ‚ΡŒ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ Π½Π° запрос Ρ‚ΠΎΠ»ΡŒΠΊΠΎ, Ссли срок ΠΊΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ записи Π΅Ρ‰Π΅ Π½Π΅ истСк – Π² ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠΌ случаС Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π·Π°Π±ΠΈΡ€Π°Ρ‚ΡŒΡΡ с сСрвСра. Π’ΠΎΡ‚ возмоТная рСализация Π½ΠΎΠ²ΠΎΠ³ΠΎ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€Π°:

        from functools import lru_cache, wraps
from datetime import datetime, timedelta

def timed_lru_cache(seconds: int, maxsize: int = 128):
    def wrapper_cache(func):
        func = lru_cache(maxsize=maxsize)(func)
        
        # инструмСнтированиС Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€Π° двумя Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π°ΠΌΠΈ,
        # ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²Π»ΡΡŽΡ‰ΠΈΠΌΠΈ врСмя ΠΆΠΈΠ·Π½ΠΈ кэша lifetime
        # ΠΈ Π΄Π°Ρ‚Ρƒ истСчСния срока Π΅Π³ΠΎ дСйствия expiration
        func.lifetime = timedelta(seconds=seconds)
        func.expiration = datetime.utcnow() + func.lifetime

        @wraps(func)
        def wrapped_func(*args, **kwargs):
            if datetime.utcnow() >= func.expiration:
                func.cache_clear()
                func.expiration = datetime.utcnow() + func.lifetime

            return func(*args, **kwargs)

        return wrapped_func

    return wrapper_cache
    

Π”Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ @timed_lru_cache Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠ΅Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ для опСрирования Π²Ρ€Π΅ΠΌΠ΅Π½Π΅ΠΌ ΠΆΠΈΠ·Π½ΠΈ записСй Π² кэшС (Π² сСкундах) ΠΈ ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ΠΎΠΌ кэша.

Код ΠΎΠ±ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ΠΎΠΌ @lru_cache. Π­Ρ‚ΠΎ позволяСт Π½Π°ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΡƒΠΆΠ΅ Π·Π½Π°ΠΊΠΎΠΌΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ ΠΊΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ.

ΠŸΠ΅Ρ€Π΅Π΄ доступом ΠΊ записи Π² кэшС Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ провСряСт, Π½Π΅ наступила Π»ΠΈ Π΄Π°Ρ‚Π° истСчСния срока дСйствия. Если это Ρ‚Π°ΠΊ, Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ ΠΎΡ‡ΠΈΡ‰Π°Π΅Ρ‚ кэш ΠΈ ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎ вычисляСт врСмя ΠΆΠΈΠ·Π½ΠΈ ΠΈ срок дСйствия. ВрСмя ΠΆΠΈΠ·Π½ΠΈ распространяСтся Π½Π° кэш Π² Ρ†Π΅Π»ΠΎΠΌ, Π° Π½Π΅ Π½Π° ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Π΅ ΡΡ‚Π°Ρ‚ΡŒΠΈ.

ΠšΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ статСй с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π½ΠΎΠ²ΠΎΠ³ΠΎ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€Π°

Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π½ΠΎΠ²Ρ‹ΠΉ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ @timed_lru_cache с Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ monitor(), Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€Π΅Π΄ΠΎΡ‚Π²Ρ€Π°Ρ‚ΠΈΡ‚ΡŒ скачиваниС с сСрвСра содСрТимого ΡΡ‚Π°Ρ‚ΡŒΠΈ ΠΏΡ€ΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ Π½ΠΎΠ²ΠΎΠΌ запросС. Π‘ΠΎΠ±Ρ€Π°Π² ΠΊΠΎΠ΄ Π² ΠΎΠ΄Π½ΠΎΠΌ мСстС, ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠΌ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚:

        import feedparser
import requests
import ssl
import time

from functools import lru_cache, wraps
from datetime import datetime, timedelta

if hasattr(ssl, "_create_unverified_context"):
    ssl._create_default_https_context = ssl._create_unverified_context

def timed_lru_cache(seconds: int, maxsize: int = 128):
    def wrapper_cache(func):
        func = lru_cache(maxsize=maxsize)(func)
        func.lifetime = timedelta(seconds=seconds)
        func.expiration = datetime.utcnow() + func.lifetime

        @wraps(func)
        def wrapped_func(*args, **kwargs):
            if datetime.utcnow() >= func.expiration:
                func.cache_clear()
                func.expiration = datetime.utcnow() + func.lifetime

            return func(*args, **kwargs)

        return wrapped_func

    return wrapper_cache

@timed_lru_cache(60)
def get_article_from_server(url):
    print("ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΡΡ‚Π°Ρ‚ΡŒΠΈ с сСрвСра...")
    response = requests.get(url)
    return response.text

def monitor(url):
    maxlen = 45
    while True:
        try:
            print("\nΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ Π»Π΅Π½Ρ‚Ρƒ...")
            feed = feedparser.parse(url)

            for entry in feed.entries[:5]:
                if "python" in entry.title.lower():
                    truncated_title = (
                        entry.title[:maxlen] + "..."
                        if len(entry.title) > maxlen
                        else entry.title
                    )
                    print(
                        "Π‘ΠΎΠ²ΠΏΠ°Π΄Π΅Π½ΠΈΠ΅:",
                        truncated_title,
                        len(get_article_from_server(entry.link)),
                    )

            time.sleep(5)
        except KeyboardInterrupt:
            break
    
        >>> monitor("https://realpython.com/atom.xml")
ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΡΡ‚Π°Ρ‚ΡŒΠΈ с сСрвСра...
Π‘ΠΎΠ²ΠΏΠ°Π΄Π΅Π½ΠΈΠ΅: The Real Python Podcast – Episode #35: Securi... 28704
ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΡΡ‚Π°Ρ‚ΡŒΠΈ с сСрвСра...
Π‘ΠΎΠ²ΠΏΠ°Π΄Π΅Π½ΠΈΠ΅: PyPy: Faster Python With Minimal Effort 67387
ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΡΡ‚Π°Ρ‚ΡŒΠΈ с сСрвСра...
Π‘ΠΎΠ²ΠΏΠ°Π΄Π΅Π½ΠΈΠ΅: Handling Missing Keys With the Python default... 33224
ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΡΡ‚Π°Ρ‚ΡŒΠΈ с сСрвСра...
Π‘ΠΎΠ²ΠΏΠ°Π΄Π΅Π½ΠΈΠ΅: Use Sentiment Analysis With Python to Classif... 158400
ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΡΡ‚Π°Ρ‚ΡŒΠΈ с сСрвСра...
Π‘ΠΎΠ²ΠΏΠ°Π΄Π΅Π½ΠΈΠ΅: The Real Python Podcast – Episode #34: The Py... 29576

ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ Π»Π΅Π½Ρ‚Ρƒ...
Π‘ΠΎΠ²ΠΏΠ°Π΄Π΅Π½ΠΈΠ΅: The Real Python Podcast – Episode #35: Securi... 28704
Π‘ΠΎΠ²ΠΏΠ°Π΄Π΅Π½ΠΈΠ΅: PyPy: Faster Python With Minimal Effort 67387
Π‘ΠΎΠ²ΠΏΠ°Π΄Π΅Π½ΠΈΠ΅: Handling Missing Keys With the Python default... 33224
Π‘ΠΎΠ²ΠΏΠ°Π΄Π΅Π½ΠΈΠ΅: Use Sentiment Analysis With Python to Classif... 158400
Π‘ΠΎΠ²ΠΏΠ°Π΄Π΅Π½ΠΈΠ΅: The Real Python Podcast – Episode #34: The Py... 29576
    

ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, ΠΊΠ°ΠΊ ΠΊΠΎΠ΄ ΠΏΠ΅Ρ‡Π°Ρ‚Π°Π΅Ρ‚ сообщСниС Β«ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΡΡ‚Π°Ρ‚ΡŒΠΈ с сСрвСра ...Β» ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π²ΠΎΠΌ доступС ΠΊ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΌ ΡΡ‚Π°Ρ‚ΡŒΡΠΌ. ПослС этого, Π² зависимости ΠΎΡ‚ скорости cΠ΅Ρ‚ΠΈ, сцСнарий Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΠ·Π²Π»Π΅ΠΊΠ°Ρ‚ΡŒ ΡΡ‚Π°Ρ‚ΡŒΠΈ ΠΈΠ· кэша нСсколько Ρ€Π°Π·, ΠΏΡ€Π΅ΠΆΠ΄Π΅ Ρ‡Π΅ΠΌ снова обратится ΠΊ сСрвСру.

Π’ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½ΠΎΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ скрипт пытаСтся ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ доступ ΠΊ ΡΡ‚Π°Ρ‚ΡŒΡΠΌ ΠΊΠ°ΠΆΠ΄Ρ‹Π΅ 5 сСкунд, Π° срок дСйствия кэша истСкаСт Ρ€Π°Π· Π² ΠΌΠΈΠ½ΡƒΡ‚Ρƒ.

Π—Π°ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅

ΠšΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ – Π²Π°ΠΆΠ½Ρ‹ΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄ ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΠΈ, ΠΏΠΎΠ²Ρ‹ΡˆΠ°ΡŽΡ‰ΠΈΠΉ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ любой ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠΉ систСмы. ПониманиС Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ ΠΊΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅, являСтся Ρ„ΡƒΠ½Π΄Π°ΠΌΠ΅Π½Ρ‚Π°Π»ΡŒΠ½Ρ‹ΠΌ шагом Π½Π° ΠΏΡƒΡ‚ΠΈ ΠΊ Π΅Π³ΠΎ эффСктивному Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡŽ Π² ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½Ρ‹ΠΉ ΠΊΠΎΠ΄.

Π’ этом ΡƒΡ€ΠΎΠΊΠ΅ ΠΌΡ‹ ΠΊΡ€Π°Ρ‚ΠΊΠΎ рассмотрСли:

  • ΠΊΠ°ΠΊΠΈΠ΅ Π±Ρ‹Π²Π°ΡŽΡ‚ стратСгии ΠΊΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ;
  • ΠΊΠ°ΠΊ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ LRU-ΠΊΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π² Python;
  • ΠΊΠ°ΠΊ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ @lru_cache;
  • ΠΊΠ°ΠΊ рСкурсивный ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ Π² сочСтании с ΠΊΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ‚ достаточно быстро Ρ€Π΅ΡˆΠΈΡ‚ΡŒ Π·Π°Π΄Π°Ρ‡Ρƒ.

Π‘Π»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ шагом ΠΊ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… стратСгий ΠΊΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ Π² Π²Π°ΡˆΠΈΡ… прилоТСниях ΠΌΠΎΠΆΠ΅Ρ‚ ΡΡ‚Π°Ρ‚ΡŒ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° cachetools, ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΡŽΡ‰Π°Ρ особыС Ρ‚ΠΈΠΏΡ‹ Π΄Π°Π½Π½Ρ‹Ρ… ΠΈ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€Ρ‹, ΠΎΡ…Π²Π°Ρ‚Ρ‹Π²Π°ΡŽΡ‰ΠΈΠ΅ самыС популярныС стратСгии ΠΊΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ.

Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊΠΈ

ΠœΠ•Π ΠžΠŸΠ Π˜Π―Π’Π˜Π―

ΠšΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ

Π’ΠΠšΠΠΠ‘Π˜Π˜

Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ вакансию

Π›Π£Π§Π¨Π˜Π• БВАВЬИ ПО Π’Π•ΠœΠ•