[Python] lru_cache

2022. 9. 28. 20:48·Python/Python
반응형

[Python] lru_cache 

0. 개요

LRU(Last Recently Used) 는 운영체제 OS에서 메모리 관리에서 Page 교체에서 사용되는 알고리즘 중 하나로
가장 오랫동안 사용하지 않은 것을 교체하는 방식입니다

  • 알고리즘 설명 : https://www.geeksforgeeks.org/lru-cache-implementation/

Python에서는 @lru_cache 로 데코레이터로 기능을 제공해주고 있습니다.

1. 기대 효과

  • Memorization 으로 추가 계산 감소
  • CPU-Bound 감소

2. Sample Code

  • lru_cache 데코레이터는 실행 함수에 3가지 함수를 추가합니다.
    • 사용 방법은 @lru_cache(maxsize=128, typed=False)
      • maxsize : lru_cache에 입력된 호출 기억하고 있을 크기
      • typed : 고정 타입 사용 유무
    • cache_parameters() : 데코레이터 입력 값
    • cache_info() : 캐시 정보
    • cache_clear() : 캐시 지우기
import random
from decimal import Decimal
from functools import lru_cache
from random import choice

class Message:
    HTTP_SUCCESS = (200, "Success")
    HTTP_CREATED = (201, "Created")
    HTTP_BAD_REQUEST = (400, "Bad request")
    HTTP_NOT_FOUND = (404, "Not found")

    USER_NOT_FOUND = (1000, "User not found")
    USER_EMAIL_EXIST = (1010, "User email already exist")

@lru_cache
def get_message():
    return Message

def rand() -> str:
    return choice([
        "HTTP_SUCCESS", "HTTP_CREATED", "HTTP_BAD_REQUEST", "HTTP_NOT_FOUND",
    ])

@lru_cache(maxsize=5, typed=True)
def calc_something(a: int, b: int) -> int:
    return a * b

class Stock:

    def __init__(self, name: str, price: Decimal, discount: Decimal):
        self.name = name
        self.price = price
        self.discount = discount

@lru_cache(typed=True)
def calc_pay_price(price: Decimal, discount: Decimal) -> Decimal:
    return price - discount

if __name__ == '__main__':
    print("### Config, Message 등 고정 값(?) 같은 것들")
    for _ in range(10):
        print(getattr(get_message(), rand()), '\t\t', get_message.cache_info())

    print("# 이후에도 메모지에이션 되어 있음")
    print(get_message().HTTP_SUCCESS, '\t\t', get_message.cache_info())
    print(get_message().USER_NOT_FOUND, '\t\t', get_message.cache_info())

    print("\n\n### 단순 계산")
    for _ in range(10):
        rand_int = random.randint(0, 10)
        print(calc_something(rand_int, rand_int), '\t\t', calc_something.cache_info())

    print("\n\n### 엔티티 계산")
    stocks = [
        Stock("Product-1", Decimal(100), Decimal(10)),
        Stock("Product-2", Decimal(200), Decimal(10)),
        Stock("Product-3", Decimal(300), Decimal(10)),
        Stock("Product-4", Decimal(100), Decimal(10)),
        Stock("Product-5", Decimal(400), Decimal(10)),
        Stock("Product-6", Decimal(200), Decimal(10)),
    ]

    for stock in stocks:
        print(calc_pay_price(stock.price, stock.discount), "\t\t", calc_pay_price.cache_info())

3. Sample Code Result

### Config, Message 등
(200, 'Success')                CacheInfo(hits=0, misses=1, maxsize=128, currsize=1)
(200, 'Success')                CacheInfo(hits=1, misses=1, maxsize=128, currsize=1)
(400, 'Bad request')            CacheInfo(hits=2, misses=1, maxsize=128, currsize=1)
(400, 'Bad request')            CacheInfo(hits=3, misses=1, maxsize=128, currsize=1)
(201, 'Created')                CacheInfo(hits=4, misses=1, maxsize=128, currsize=1)
(404, 'Not found')              CacheInfo(hits=5, misses=1, maxsize=128, currsize=1)
(404, 'Not found')              CacheInfo(hits=6, misses=1, maxsize=128, currsize=1)
(200, 'Success')                CacheInfo(hits=7, misses=1, maxsize=128, currsize=1)
(200, 'Success')                CacheInfo(hits=8, misses=1, maxsize=128, currsize=1)
(404, 'Not found')              CacheInfo(hits=9, misses=1, maxsize=128, currsize=1)

# 이후에도 메모지에이션 되어 있음
(200, 'Success')                CacheInfo(hits=10, misses=1, maxsize=128, currsize=1)
(1000, 'User not found')      CacheInfo(hits=11, misses=1, maxsize=128, currsize=1) 

### 단순 계산
4          CacheInfo(hits=0, misses=1, maxsize=5, currsize=1)
16          CacheInfo(hits=0, misses=2, maxsize=5, currsize=2)
0          CacheInfo(hits=0, misses=3, maxsize=5, currsize=3)
4          CacheInfo(hits=1, misses=3, maxsize=5, currsize=3)
0          CacheInfo(hits=2, misses=3, maxsize=5, currsize=3)
81          CacheInfo(hits=2, misses=4, maxsize=5, currsize=4)
0          CacheInfo(hits=3, misses=4, maxsize=5, currsize=4)
100      CacheInfo(hits=3, misses=5, maxsize=5, currsize=5)
9          CacheInfo(hits=3, misses=6, maxsize=5, currsize=5)
9          CacheInfo(hits=4, misses=6, maxsize=5, currsize=5)

### 엔티티 계산
90              CacheInfo(hits=0, misses=1, maxsize=128, currsize=1)
190          CacheInfo(hits=0, misses=2, maxsize=128, currsize=2)
290          CacheInfo(hits=0, misses=3, maxsize=128, currsize=3)
90              CacheInfo(hits=1, misses=3, maxsize=128, currsize=3)
390          CacheInfo(hits=1, misses=4, maxsize=128, currsize=4)
190          CacheInfo(hits=2, misses=4, maxsize=128, currsize=4)

Ref

  • https://stlee321.tistory.com/entry/functools함수-결과-캐싱-cache-cachedproperty-lrucache
  • https://medium.com/geekculture/python-lru-cache-2680be8045aa
728x90
반응형
저작자표시 비영리 변경금지 (새창열림)
'Python/Python' 카테고리의 다른 글
  • [Python] 파이썬 Thread and Pool Manager
  • [Python] Linter 비교
  • [Python] Object class __slots__를 이용한 성능 개선
  • [Python] Concurrency Thread Decorator - 3
상쾌한기분
상쾌한기분
  • 상쾌한기분
    상쾌한기분
    상쾌한기분
  • 전체
    오늘
    어제
    • 분류 전체보기 (251)
      • Python (44)
        • Python (26)
        • Django (6)
        • Flask (4)
        • Open Source (6)
      • Kotlin & Java (5)
        • Spring (2)
        • 프로젝트 (1)
      • Go (11)
      • Database (24)
        • MySQL (21)
        • Redis (3)
      • Infrastructure (2)
        • CDC (4)
        • Kafka (5)
        • Prometheus (2)
        • Fluentd (11)
        • Docker (1)
        • Airflow (2)
        • VPN (2)
      • IT (26)
        • AI (9)
        • Langchain (8)
        • Web (18)
        • Git (8)
        • 리팩토링 (9)
        • Micro Service Architecture (8)
        • Clean Code (16)
        • Design Pattern (0)
        • 수학 (1)
        • 알고리즘 (14)
      • OS (14)
        • Centos (10)
        • Ubuntu (3)
        • Mac (1)
      • Search Engine (2)
        • ElasticSearch (1)
        • Lucene Solr (1)
      • PHP (2)
        • Laravel (1)
        • Codeigniter (1)
  • 블로그 메뉴

    • Github 방문
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    Langchain
    go
    파이썬
    fluentd
    CDC
    Kafka
    performance
    MYSQL
    git
    docker
    티스토리챌린지
    오블완
    prompt
    python
    백준
    ollama
    Golang
    Redis
    LLM
    http
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
상쾌한기분
[Python] lru_cache
상단으로

티스토리툴바