Lazy Evaluation

고준영·2021년 8월 5일
2

Python🐍

목록 보기
5/7
post-thumbnail

1. What is Lazy Evaluation

1. 위키백과

컴퓨터 프로그래밍에서 느긋한 계산법(Lazy evaluation)은 계산의 결과값이 필요할 때까지 계산을 늦추는 기법이다. 두 가지 관련된 항목들이 있는데 지연 계산법과 최소 계산법이다.
느긋하게 계산하면 필요없는 계산을 하지 않으므로 실행을 더 빠르게 할 수 있고, 복합 수식을 계산할 때 오류 상태를 피할 수 있고, 무한 자료 구조를 쓸 수 있고, 미리 정의된 것을 이용하지 않고 보통 함수로 제어 구조를 정의할 수 있다.

느긋한 계산법을 사용하는 언어들은 "이름으로 호출"하거나 "필요할 때 호출"하는 계산 전략을 사용하는 것으로 나눌 수 있다. 하스켈과 같은 대부분의 실제 느긋한 언어들은 성능상의 이유로 "필요할 때 호출" 전략을 사용한다.
그러나 느긋한 계산법을 이론적으로 표현한 것들은 간편하게 "이름으로 호출"하기도 한다.
느긋한 계산법의 반대되는 계산법은 조급한 계산법이 있는데 엄격한 계산법이라고도 한다. 조급한 계산법은 대부분의 프로그래밍 언어가 동작하는 방식이다.

2. 정리✏️

내가 커피숖의 사장이라고 생각해보자!!☕️
출근 시간에 아메리카노가 평균적으로 20잔 정도 팔리고, 이를 위해서 커피를 20잔을 만들어 놓았다고 생각해보자.
근데 이를 어쩌나 우리 카페 앞에서 무료 커피 증정 행사를 하고있네,,,?(아니 꼭 그런건 왜 우리 가게 앞에서만...)
이로 인해 단골 고객의 주문인 2잔을 빼고 18잔을 팔지 못했다!!!😱
그런데 내가 만약 커피를 미리 만들어 놓지 않고, 주문이 들어올 때마다 만들었다고 생각하면 커피를 2잔만 만들었을 것이다.
물론 현실에서의 효율과 컴퓨터 세상 사이의 차이는 있겠지만 효율을 계산해보자!!💻
커피를 20잔 만들어 놓은 경우를 예시1 이라고 하고 커피를 2잔 만들 경우를 예시2라고 하자
예시1
커피 20잔 만드는 노력 + 20잔의 원가
예시2
커피 2잔 만드는 노력 + 2잔의 원가
효율을 계산해보면 예시2>>>>>>>>넘사>>>>>>>예시1 이다.
이렇게 주문이 들어오면 노력(커피 만들기)을 행하는 것을
Lazy Evaluation 라고 한다.


2. Analysis Lazy Evaluation from code

def print_iter(iter):
    for element in iter:
        print(element)

def lazy_return(num):
    print("sleep 1s")
    time.sleep(1)
    return num

L = [ 1,2,3]    

print("comprehension_list=")
comprehension_list = [ lazy_return(i) for i in L ]
print_iter(comprehension_list)

print("generator_exp=")
generator_exp = ( lazy_return(i) for i in L )
print_iter(generator_exp)
  • 위 코드의 수행결과는 다음과 같다

  • sleep 1s가 3번 출력 후 123 이 출력 된 것을 보아 comprehension_list는 for loop을 모두 돌아서 list를 미리 만들어 만들어 놓고(*예시1커피☕️ 미리 만들어 놓기) 만들어진 List의 내용을 출력해주는 것을 볼 수 있다.

반면에

  • generator_exp(generator expression을 통해 lazy_evaluation)을 보면 sleep와 {숫자} 가 반복되어 나오는 것을 볼 수 있다. 이를 통해 lazy_evaluation란 미리 만들어 놓지 않고, 필요할 때(예시2주문이 들어왔을 때 ☕️생성) for loop를 돌아 한단계 한단계 loop를 수행하는 것을 유추할 수 있다.

3. Why use it?

import random

counter = random.randrange(1, 11)  # 1부터 10사이의 랜덤 값 생성
counter_comprehension = counter
counter_lazy = counter
print(f"몇잔 팔았는지: {counter}")

def Let_make_list():
    print("커피 만들기")
    return 1

#예시1
print("리스트 만들기(커피 만들기)")
comprehension_list = [Let_make_list () for x in range(10)]

print("리스트 사용(커피 판매)")
for item in comprehension_list:
    counter_comprehension -= 1
    print("커피판매")
    if counter_comprehension == 0:
        break

#예시2
print("리스트 만들기(커피 만들기)")
lazy_list = (Let_make_list () for x in range(10))

print("리스트 사용(커피 판매)")
for item in lazy_list:
    counter_lazy -= 1
    print("커피판매")
    if counter_lazy == 0:
        break

위 코드는 커피를 몇잔 파는지 임의의 숫자를 받아 예시1예시2를 비교하는 코드이다. 아래의 결과를 확인해보자.

  • 커피를 총 4잔 팔았는데 comprehension으로(예시1의 방법)만들 리스트는 모두 다 만들어 놓고 판매했으며, lzay로(예시2의 방법) 만든 것은 커피를 4번만 만든것을 알 수 있다.
  • 위의 결과만 보아도 알 수 있듯이 lazy방식이 조금 더 효율적인것을 알 수 있다.
  • 하지만 위의 방식은 우리가 커피를 얼마나 판매 할지 모르는 경우!!에 효율적이고 몇잔을 판매 할지 알고있다면 한번에 다 만드는 것이 효율적이다.
  • 결론 상황에 맞는 list making을 통해 효율적으로 사용해야 한다!!

4. conclusion

Django를 공부할 때 정말로 의문이었던 장고ORM은 Lazy Evaluation 방식을 사용하고 있기 때문에 DB에 접근이 효율적으로 이루어진다. 라고 정말 듣기만 했고, 실제로 사용할 때 DB에 접근이 된다!! 라고 니꼬가 항상 말하는 것만 들었지 구동의 원리는 알지 못했다.
DB에 접근 할 때 이렇게 Lazy Evaluation 방식을 사용하면 좋은점이 받아와야 하는 결과값이 3번의filter를 거치고 1번의exclude 될 때
Lazy Evaluation 방식을 사용하면 마지막에 한번 queryset이 만들어 지는데,
Lazy Evaluation 방식을 사용하지 않는다면 총 4번의 queryset을 만들어야 한다.

점점 배워야 하는 Django와 가까워지고 있는 느낌이 든다!! python에 대해 조금 더 공부하고, 장고를 사용하면 장고에 지배당하여 사용하는 개발자가 아닌 장고를 점령하여 내가 사용하고 싶은 부분은 사용하고, 아닌 부분은 조금씩 내 입맛에 맞게 수정하여 사용 할 수 있는 개발자가 될 수 있을것 같다...!!

느리더라도 정확하게 공부하자🐍
21.08.05 위코드 1주차 목요일

profile
코드짜는귤🍊 풀스택을 지향하는 주니어 개발자 입니다🧡

1개의 댓글

comment-user-thumbnail
2021년 8월 5일

느리더라도 정확하게...! 멋진말이에요!
급한 걸음이 아니라 단단한 걸음을 걸어야겠습니다.
좋은글 감사합니다!

답글 달기