Przeanalizujmy poniższy przykład:
from datetime import datetime
import time
def czekacz():
time.sleep(1)
return 1
poczatek=datetime.now()
for x in range(10):
czekacz()
koniec=datetime.now()
print(koniec-poczatek)
Mam funkcję "czekacz" której jedynym zadaniem jest poczekanie 1 sekundy i zwrócenie liczby 1. Funkcja ta jest wykonywana dziesięciokrotnie, a na koniec wypisywany jest czas realizacji całości. Kod w powyższym stanie wykonuje się nieco ponad 10 sekund. Przyjmijmy teraz że zamiast oczekiwania 1 sekundy mamy do wykonania jakieś złożone obliczenie które trwa. Jeśli funkcja dla danego outputu daje nam zawsze ten sam wynik (jest deterministyczna) to wynik tej funkcji można umieścić w cache i ponownie jej reużyć przy ponownym wywołaniu funkcji z tą samą wartością dla niej zamiast obliczać po raz wtóry. Do tego służy moduł "functools" i zawarty w nim dekorator "lru_cache". Przeanalizujmy teraz ten przykład po pewnych zmianach. Nad funkcją czekacz wpisałem dekorator "@functools.lru_cache". Dekorator ten sprawia że wynik działania naszej funkcji czekacz ląduje w cache i jest pobierana przy kolejnych wywołaniach tej funkcji dla tych samych argumentów (w naszym przypadku brak argumentu - funkcja zawsze zwraca 1):
from datetime import datetime
import time
import functools
@functools.lru_cache(maxsize=None)
def czekacz():
time.sleep(1)
return 1
poczatek=datetime.now()
for x in range(10):
czekacz()
koniec=datetime.now()
print(koniec-poczatek)
Tym razem wykonanie całości zajeło nieco ponad 1 sekundę! Wynika to z tego, że kolejne wywołania tej funkcji odczytywały wartość z cache nie wykonując tej funkcji. Argument tego dekoratora (maxsize=None) określa dla ilu wartości wejściowych funkcja ma przechowywać dane w cache.
Cache można stosować tylko do funkcji deterministycznych - czyli w skrócie takich które dla tych samych parametrów wejściowych zwrócą nam zawsze te same dane wyjściowe.
Komentarze (0)
Brak komentarzy...