decorator가 유용하게 사용되는 경우 중 하나가 특정 function 등의 수행시간 측정이다.
function으로 decorator를 만드는 경우에 대한 정리는 이전에 했기 때문에 여기선 class로 작성한다.
해당 decorator는 arguments를 통해
- 어떤 단위로 측정할지와
- cpu시간만을 측정할지 등을 선택할 수 있게 구성함.
code는 다음과 같음.
import time
class DsElapsedTime:
def __init__(self, is_sec=True, only_cpu=False):
# decorator가 동작 방식을 정의하는 변수 초기화.
self.is_sec = is_sec
self.only_cpu = only_cpu
def __call__(self, func): #decorate할 func 을 argument로 받음.
def wrap_func(*args, **kargs):
if self.only_cpu == False:
start_t = time.perf_counter_ns()
mode = 'real time'
else:
start_t = time.process_time_ns()
mode = 'cpu time'
# func 수행.
ret_v = func(*args, **kargs)
if self.only_cpu == False:
end_t = time.perf_counter_ns()
else:
end_t = time.process_time_ns()
elapsed_t = end_t - start_t
unit = 'nano-sec'
if self.is_sec:
elapsed_t = elapsed_t/1000_000_000
unit = 'sec'
print(f'{func.__name__} elapsed: {elapsed_t: .4f} sec ({mode})')
return ret_v
return wrap_func
@DsElapsedTime()
def test_func():
time.sleep(10)
test_func()
@DsElapsedTime(only_cpu=True)
def test_func():
time.sleep(10)
test_func()
time.perf_counter_ns
:time.time_ns
과 유사하지만 보다 높은 time resolution을 지원함. 실제 수행시간을 nano-second 단위로 반환.time.process_time_ns
: 실제 cpu에서 처리된 시간만을 반환함. 역시 nano-second 단위임.
_ns
만 떼어내면 second 단위로 반환이 이루어짐.
결과는 다음과 같음.
test_func elapsed: 10.0075 sec (real time)
test_func elapsed: 0.0545 sec (cpu time)
위의 예에서는 생성자에서 parameter를 가지고 있기 때문에, decorator부분에서 parenthesis가 기재되어야 함.
즉, @DsElapsedTime
로만 처리하면 에러가 발생한다.
Parameter가 필요없는 경우엔 다음과 같이 구현하면 된다.
- 생성자에서 감싸줄 함수를 argument로 받음.
__call__
에서 감싸줄 함수와 같은 parameters를 가지면 됨.
import time
class DsElapsedTime:
def __init__(self, func):
# decorate 할 func을 생성자에서 받음.
self.func = func
def __call__(self, *args, **kargs): #decorate할 func의 argument와 같아야함.
start_t = time.perf_counter()
mode = 'real time'
# func 수행.
ret_v = self.func(*args, **kargs)
end_t = time.perf_counter()
elapsed_t = end_t - start_t
unit = 'sec'
print(f'{self.func.__name__} elapsed: {elapsed_t: .4f} sec ({mode})')
return ret_v
@DsElapsedTime
def test_func():
time.sleep(10)
test_func()
- second단위로 실제 수행시간을 반환하도록 수정함.(parameter로 변경이 안됨. 고정형.)
결과는 다음과 같음.
test_func elapsed: 10.0108 sec (real time)
더 읽어보면 좋은 자료.
https://mebadong.tistory.com/106
728x90
'Python' 카테고리의 다른 글
[Python] functools.partial (0) | 2023.08.25 |
---|---|
[Python] instance methods, class methods, and static methods (0) | 2023.08.20 |
[Python] Decorator (0) | 2023.08.18 |
[Python] PEP 8 : Style Guide for Python Code (0) | 2023.08.04 |
[Python] asterisk * 사용하기 : unpacking, packing (0) | 2023.07.30 |