Lazy Evaluation 이란 프로그래밍이 동작하는 데 사용되는 계산 전략의 한 종류를 말한다.

 

일반적인 프로그래밍에서 계산식이 즉발적으로 수행되는데 비해 Lazy Evaluation 은 해당 계산식의 실제 수행을 필요할 때까지 늦춘다.

이렇게 되면 장점으로는 필요하지 않은 시점에서 해당 식의 "불필요한 수행" 을 막을 수 있으며 어떤 경우에는 실제 수행되는 시점에조차 수행 과정에서의 불필요한 동작들을 최적화시킬 수 있다.

다음의 예시를 확인해보자.

 

위의 코드에서 일반적인 수행이라면 checked 의 값은 무조건 먼저 계산이 된다.

foo 함수가 얼마만큼의 비용을 수반하더라도, foo(val) 의 Return 값이 checked 가 가져야할 값이므로 일반적인 수행에서 checked 값은 foo 함수의 결과를 저장하며 그에 따라 아래의 조건식을 수행하게 된다.

 

만약 위의 코드가 Lazy 하게 동작한다면 흐름은 조금 다르다.

먼저 변수 checked 는 foo 메서드가 val 을 argument 로 전달받아서 수행하게된 "어떤 값" 이라고 간주되고, 이를 이후 필요한 시점, 즉 조건문을 체크하는 아래 로직에서 실제로 사용하게 된다.

 

첫번째 조건문인 if(true && checked) 조건문에서 foo 함수는 호출되게 된다. checked 가 true 여야지만 해당 조건이 참이되기 때문이다.

하지만 두번째 조건문에서는 foo 함수는 호출되지 않는다. 알다시피 true 가 이미 or 의 조건문에 포함되어 있기 때문에 compiler 는 최적화를 통해 이를 수행하지 않는다.

 

<참고로 위의 예제코드는 이해를 돕기 위해 작성한 것일 뿐 실제로 Lazy 하게 동작하지 않음을 주의한다.>

 

이러한 Lazy Evaluation 은 프로그래밍에서 종종 사용되는 개념이며 실제로 많은 경우에 퍼포먼스의 향상을 가져올 수 있다.

 

Java에서도 Lazy Evaluation 을 사용할 수 있으며 보통 Java8 의 Lambda 를 이용해 이를 지원한다.

 

이제 위의 메서드를 Lambda 식을 이용해서 Lazy Evaluation 형태로 바꾸어 보고 비교해보자.

 

 

위의 예제를 변형한 코드이다.

코드에서는 Lazy Evaluation 을 함수형 인터페이스의 Supplier 메서드를 이용해 구현한 모습으로,

위의 main 동작에서 가장 마지막 조건문의 수행 시, foo 함수는 호출되지 않는다.

 

이와 같은 Lazy Evaluation 을 이용하면 사소한 부분이지만 만약 foo 함수의 비용이 막대한 경우에 큰 성능 상 이점을 가져올 수 있다.

 

특히 Lambda 가 대중화되고 Lazy Evaluation 과 같은 처리가 익숙해진 최근의 추세에서 확실히 개념을 이해하고 사용하는 것이 중요하겠다.

 

+ Recent posts