lru_cache : 캐싱 메모리

2025. 2. 8. 10:09·파이썬/Basic
반응형

lru_cache는 Python의 functools 모듈에서 제공하는 데코레이터로, Least Recently Used(LRU) 캐싱 메커니즘을 구현합니다. 함수의 호출 결과를 메모리에 캐싱하여 동일한 입력에 대한 반복 계산을 방지합니다.

기본 사용법

from functools import lru_cache

@lru_cache(maxsize=128)
def fibonacci(n):
    if n < 2:
        return n
    return fibonacci(n-1) + fibonacci(n-2)

# 실행 예시
print(fibonacci(100))  # 매우 빠르게 계산됨

 

캐시 크기와 성능 측정

import time
from functools import lru_cache

def measure_time(func, *args):
    start = time.time()
    result = func(*args)
    end = time.time()
    return result, end - start

# 캐시 크기 다르게 설정하여 비교
@lru_cache(maxsize=None)  # 무제한 캐시
def factorial1(n):
    return n * factorial1(n-1) if n else 1

@lru_cache(maxsize=128)   # 제한된 캐시
def factorial2(n):
    return n * factorial2(n-1) if n else 1

# 성능 비교
for n in [100, 500, 1000]:
    result1, time1 = measure_time(factorial1, n)
    result2, time2 = measure_time(factorial2, n)
    print(f"n={n}:")
    print(f"Unlimited cache: {time1:.6f}s")
    print(f"Limited cache: {time2:.6f}s")

 

캐시 정보 확인과 관리

from functools import lru_cache

@lru_cache(maxsize=32)
def expensive_computation(x, y):
    # 복잡한 계산 시뮬레이션
    return x * y ** 2

# 캐시 통계 확인
def print_cache_info(func):
    info = func.cache_info()
    print(f"Hits: {info.hits}")        # 캐시 히트 횟수
    print(f"Misses: {info.misses}")    # 캐시 미스 횟수
    print(f"Maxsize: {info.maxsize}")  # 최대 캐시 크기
    print(f"Current size: {info.currsize}")  # 현재 캐시 크기

# 캐시 사용 예시
for i in range(5):
    expensive_computation(2, 3)
    expensive_computation(3, 4)

print_cache_info(expensive_computation)

# 캐시 초기화
expensive_computation.cache_clear()

 

실제 활용 사례

API 요청 캐싱

import requests
from functools import lru_cache
from datetime import datetime, timedelta

@lru_cache(maxsize=100)
def get_weather_data(city: str, date: str):
    """날씨 API 호출 결과를 캐싱"""
    url = f"https://api.weather.com/{city}/{date}"
    response = requests.get(url)
    return response.json()

# 사용 예시
weather = get_weather_data("seoul", "2024-02-05")

데이터베이스 쿼리 캐싱

from functools import lru_cache
from typing import Optional
import sqlite3

class DatabaseCache:
    def __init__(self):
        self.conn = sqlite3.connect('database.db')
        
    @lru_cache(maxsize=1000)
    def get_user_by_id(self, user_id: int) -> Optional[dict]:
        cursor = self.conn.cursor()
        cursor.execute("SELECT * FROM users WHERE id = ?", (user_id,))
        result = cursor.fetchone()
        return dict(zip(['id', 'name', 'email'], result)) if result else None

# 사용 예시
db = DatabaseCache()
user = db.get_user_by_id(123)  # 첫 호출: DB 쿼리 실행
user = db.get_user_by_id(123)  # 두 번째 호출: 캐시에서 반환

 

계산 비용이 높은 함수 최적화

import math
from functools import lru_cache

@lru_cache(maxsize=None)
def calculate_complex_formula(x: float, y: float, precision: int) -> float:
    """복잡한 수학적 계산을 캐싱"""
    result = 0
    for i in range(precision):
        result += math.sin(x * i) * math.cos(y * i)
    return result

# 성능 측정
def measure_performance():
    start = time.time()
    for x in range(100):
        for y in range(100):
            calculate_complex_formula(x/10, y/10, 1000)
    end = time.time()
    return end - start

 

주의사항과 최적화 팁

메모리 사용량 고려

# 메모리 사용량 모니터링
import sys

def get_size(obj):
    return sys.getsizeof(obj)

@lru_cache(maxsize=100)
def memory_intensive_function(n):
    # 큰 리스트 생성
    return [i**2 for i in range(n)]

# 메모리 사용량 체크
before = get_size(memory_intensive_function.cache_info())
memory_intensive_function(1000)
after = get_size(memory_intensive_function.cache_info())
print(f"Cache size increased by: {after - before} bytes")

 

함수 인자 제한 

from functools import lru_cache
from typing import Hashable

def make_hashable(obj):
    """객체를 해시 가능한 형태로 변환"""
    if isinstance(obj, Hashable):
        return obj
    elif isinstance(obj, dict):
        return tuple((k, make_hashable(v)) for k, v in sorted(obj.items()))
    elif isinstance(obj, (list, tuple)):
        return tuple(make_hashable(x) for x in obj)
    else:
        raise TypeError(f"Cannot make {type(obj)} hashable")

@lru_cache(maxsize=128)
def process_data(data):
    # 해시 가능한 형태로 변환 후 처리
    hashable_data = make_hashable(data)
    return str(hashable_data)

lru_cache는 적절히 사용하면 프로그램의 성능을 크게 향상시킬 수 있지만, 메모리 사용량과 캐시 크기의 균형을 잘 고려해야 합니다. 특히 대규모 애플리케이션에서는 캐시 전략을 신중하게 설계해야 합니다.

저작자표시 비영리 변경금지 (새창열림)

'파이썬 > Basic' 카테고리의 다른 글

Python JSON 라이브러리 비교: json vs ujson vs orjson  (0) 2025.02.26
Geopy : 지리 정보 다루기  (2) 2025.02.10
함수 하나로 여러 가지 처리하기? Python 오버로딩  (2) 2024.12.27
자료구조 : deque, Queue, heapq  (0) 2024.12.10
next()와 제너레이터 표현식  (1) 2024.12.09
'파이썬/Basic' 카테고리의 다른 글
  • Python JSON 라이브러리 비교: json vs ujson vs orjson
  • Geopy : 지리 정보 다루기
  • 함수 하나로 여러 가지 처리하기? Python 오버로딩
  • 자료구조 : deque, Queue, heapq
코샵
코샵
나의 코딩 일기장
    반응형
  • 코샵
    끄적끄적 코딩 공방
    코샵
    • 분류 전체보기 (724) N
      • 상품 추천 (223) N
      • MongoDB (4)
      • 하드웨어 (16) N
      • 일기장 (4)
      • Unity (138)
        • Tip (41)
        • Project (1)
        • Design Pattern (8)
        • Firebase (6)
        • Asset (2)
      • 파이썬 (13)
        • Basic (41)
        • OpenCV (8)
        • Pandas (15)
        • PyQT (3)
        • SBC(Single Board Computer) (1)
        • 크롤링 (14)
        • Fast API (29)
        • Package (6)
      • Linux (4)
      • C# (97)
        • Algorithm (11)
        • Window (7)
      • TypeScript (41)
        • CSS (10)
      • Git (11)
      • SQL (5)
      • Flutter (10)
        • Tip (1)
      • System (1)
      • BaekJoon (6)
      • Portfolio (2)
      • MacOS (1)
      • 유틸리티 (1)
      • 서비스 (6)
      • 자동화 (3)
      • Hobby (10)
        • 물생활 (10)
        • 식집사 (0)
  • 인기 글

  • 태그

    쇼핑몰리뷰
    스마트스토어리뷰
    긴유통기한우유
    codingcommunity
    codingtips
    스크립트 실행
    C#
    learntocode
    Python
    programmerlife
    리스트
    리뷰이관
    ipcamera
    파이썬
    라떼우유
    cv2
    list
    믈레코비타멸균우유
    상품 리뷰 크롤링
    셀레니움
    유니티
    rtsp
    unity
    스크립트 실행 순서
    devlife
    카페24리뷰
    카페24리뷰이관
    programming101
    appdevelopment
    리뷰관리
  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
코샵
lru_cache : 캐싱 메모리
상단으로

티스토리툴바