개발 꿀팁/PYTHON

Python 캐시 lru_cache의 소개와 설명입니다

Jammie 2022. 12. 2. 11:29
반응형

첫째, 서언입니다.
우리가 자주 이야기하는 캐싱이라는 용어는 하드 디스크의 데이터를 메모리에 저장하여 읽기 속도를 높이는 것과 더 유사하며, 예를 들어 redis라고 하면 데이터를 캐싱하는 데 자주 사용됩니다.
파이썬의 캐시(lru_cache)는 실행된 함수에 장식하여 실행된 결과를 캐시하고 다음 요청 시 해당 함수의 매개 변수가 변경되지 않으면 함수를 수행하지 않고 캐시된 결과를 직접 반환하는 캐시 장식기입니다.

그럼 그것과 redis의 차이점은 무엇인가요?어떤 장점이 있나요? 다음에 설명해 드리겠습니다

기사 목록입니다.
첫째, 서언입니다.
2. 예를 들어 설명하시오.
3. lru_cache 사용법입니다.
1. 파라미터 상세설명입니다.
1) maxsize
2)typed
2. lru_cache는 가변 인자를 지원하지 않습니다
4. lru_cache와 redis의 차이점
5. 총결산합니다.


2. 예를 들어 설명하시오.
1.이제 캐시를 사용하지 않고 두 수의 합을 구하는 함수를 작성하고 두 번 실행합니다

def test(a, b):
print('a+b 값을 계산하기 시작합니다...')
return a + b


print('1+2는:', test(1, 2)와 같습니다)
print('1+2는:', test(1, 2)와 같습니다)

실행 결과입니다

a+b 값을 계산합니다...
1+2는 다음과 같습니다: 3
a+b 값을 계산합니다...
1+2는 다음과 같습니다: 3

test가 두 번 실행된 것을 볼 수 있으며, 이제 캐시를 추가하고 다시 실행합니다

from functools import lru_cache

@lru_cache
def test(a, b):
print('a+b 값을 계산하기 시작합니다...')
return a + b

print(test(1, 2))
print(test(1, 2))

실행 결과입니다

a+b 값을 계산합니다...
1+2는 다음과 같습니다: 3
1+2는 다음과 같습니다: 3

test 함수는 한 번만 수행되었으며 두 번째 호출은 캐시된 값을 사용하여 결과를 직접 출력하는 것을 볼 수 있습니다.

2. 피보라치 수열을 재귀적으로 구할 때(피보나치 수열은 0,1,2,3,5,8번 항목 3번부터 각각 앞의 두 항목의 합과 같음) 캐시에 의한 성능 향상이 특히 두드러집니다.

캐시를 사용하지 않고 40번째 피보라치 열을 구합니다

import datetime

def fibonacci(num):
# 캐시를 사용하지 않을 때는 함수를 반복합니다
return num if num < 2 else fibonacci(num - 1) + fibonacci(num - 2)

start = datetime.datetime.now()
print(fibonacci(40))
end = datetime.datetime.now()
print( '실행 시간', end - start)

실행 시간입니다

실행시간 0:00:29.004424 입니다

캐시를 사용하여 40번 항목의 피폴라치 수열을 구합니다

@lru_cache
def fibonacci(num):
# 캐시를 사용하지 않을 때는 함수를 반복합니다
return num if num < 2 else fibonacci(num - 1) + fibonacci(num - 2)

실행 시간입니다

실행시간 0:00:00 입니다

캐시를 사용하지 않을 때 많은 함수를 반복적으로 수행해야 하는 것과 같기 때문에 두 간격은 매우 분명하며, lru_cache를 사용하면 이전에 실행된 함수 결과를 캐싱하여 다시 실행할 필요가 없습니다.

3. lru_cache 사용법입니다.
1. 파라미터 상세설명입니다.
lru_cache 소스를 보면 maxsize, typed라는 두 가지 매개 변수를 전달할 수 있습니다

def lru_cache(maxsize=128, typed=False):
    """Least-recently-used cache decorator.

    If *maxsize* is set to None, the LRU features are disabled and the cache
    can grow without bound.
	...
	"""

1) maxsize
lru_cache로 장식된 메서드의 캐시 가능한 최대 결과 수를 나타냅니다(장식된 메서드가 서로 다르면 결과가 다릅니다. 동일한 메서드가 있으면 결과가 다릅니다). 참조를 지정하지 않으면 기본값은 128로 최대 128개의 캐시 반환 결과를 나타냅니다. 128개에 도달하면 새로운 결과를 저장할 때 가장 오래된 결과가 삭제됩니다.maxsize가 None으로 들어오면 결과를 무제한으로 캐시할 수 있습니다.

2)typed
기본적으로 false는 데이터 유형을 구분하지 않음을 나타내며, True로 설정된 경우 캐시를 위한 참조 유형이 구분되며 공식적으로는 다음과 같이 설명됩니다

type이 True이면 각각 다른 유형의 파라미터를 캐시합니다.
예를 들어, f(3.0) 및 f(3)는 명백한 결과로 간주됩니다

그러나 python 3.9.8 버전에서는 type이 false일 경우 공식 테스트 방법에 따라 테스트한 결과는 다른 결과로 처리됩니다. 이때 type이 false인지 true인지 캐시가 다를 수 있습니다. 이는 공식 문서의 설명과 차이가 있습니다

from functools import lru_cache

@lru_cache
def test(a):
print('함수가 호출되었습니다...')
return a

print(test(1.0))
print(test(1))

실행 결과입니다

함수가 호출되었습니다...
1.0
함수가 호출되었습니다...
1

그러나 다중 매개변수의 경우 결과로 간주됩니다

from functools import lru_cache

@lru_cache
def test(a, b):
print('함수가 호출되었습니다...')
return a , b

print(test(1.0, 2.0))
print(test(1, 2))

실행 결과입니다

함수가 호출되었습니다...
(1.0, 2.0)
(1.0, 2.0)

typed를 true로 설정하면 캐시가 달라집니다

from functools import lru_cache

@lru_cache(typed=True)
def test(a, b):
print('함수가 호출되었습니다...')
return a , b

print(test(1.0, 2.0))
print(test(1, 2))

실행 결과입니다

함수가 호출되었습니다...
(1.0, 2.0)
함수가 호출되었습니다...
(1, 2)

전참의 개수가 1보다 클 때 비로소 관청의 설에 부합하며 관청의 예시가 잘못된 것인지 분명하지 않습니다.

2. lru_cache는 가변 인자를 지원하지 않습니다
전달된 매개변수가 dict, list 등의 가변 매개변수일 때 lru_cache는 지원되지 않으며 오류를 보고합니다

from functools import lru_cache

@lru_cache
def test(a):
print('함수가 실행되었습니다...')
return a

print(test({'a':1}))

결과를 잘못 보고했습니다

TypeError: unhashable type: 'dict'

4. lru_cache와 redis의 차이점

 

  캐시합니다                  캐시 위치입니다                 가변 인자를 지원할지 여부입니다        분산 지원 여부입니다    만료 시간 설정을 지원할 지 여부입니다         지원되는 데이터 구조입니다            별도 설치가 필요합니다
  redis        redis에서 관리하는 메모리에 캐시합니다                       네                               네                         네                           5가지 데이터 구조를 지원합니다                 네
 lru_cache     응용 프로그램 프로세스의 메모리에 캐시를 합니다.             부정하다                         부정하다                    부정하다                      사전 (인수: key, 결과: value) 입니다         부정하다                
                    응용 프로그램을 닫으면 비웁니다

5. 총결산합니다.
위의 분석 후, lru_cache 기능은 redis보다 훨씬 간단하지만 사용이 더 편리하고 작은 단량체 응용 분야에 적합합니다.캐시에 관련된 데이터의 종류가 많고 캐시를 더 잘 관리하고 싶은 경우, 또는 캐시가 필요한 데이터의 만료 시간(로그인 검증을 위한 token과 유사) 등은 redis를 사용하는 것이 lru_cache보다 우수합니다

 

반응형