ITEM 37 :: EFFECTIVE C#
안녕하세요, 37번째 시간입니다. 날이 가면 갈수록 어려워지는 게 끝이 다가오고 있음을 알려주는 듯 합니다.
이번 챕터는 쿼리를 사용할 때는 즉시 평가보다 지연 평가가 낫다, 입니다. 딱 들어서는 감이 잘 안오는 생소한 단어임이 분명합니다. 일단, 시작해보죠.
설명
-
쿼리를 정의한다고 무조건 데이터나 시퀀스를 즉각적으로 가져오는 것은 아니다. 실제로는 어떤 작업을 수행할지에 대한 절차만 정의하는 것인데, 일반적으로 이러한 방식이 더 효과적이며 실제로 쿼리의 결과를 이용하여 순회를 수행해야만 결과 데이터가 생성된다. 이를 지연 평가라고 한다.
-
가끔은 이러한 동작 방식보다는 즉각적인 데이터 생성이 필요한 경우도 있다. 마치 일반 변수처럼 즉각적으로 그 값을 얻어오는 것을 즉시 평가라고 한다.
-
따라서 쿼리를 작성할 때는 쿼리의 결과를 여러 번 순회하는 경우 어떻게 동작하기를 바라는지를 미리 고려해야 하며, 즉시 데이터의 스냅샷을 얻기 원하는지 (즉시 평가) 혹은, 그 절차만을 기술할지 (지연 평가) 고민할 필요성이 있다.
-
예제를 보면 시퀀스는 그 값을 가지고 있는 것이 아니라 시퀀스 내의 개별요소에 해당하는 그 값을 생성하는 방법을 나타내는 코드를 가지고 있는 것이다.
-
몇몇의 코드들은 무한 시퀀스가 생성되며 무한 시퀀스 내에서 쿼리구문을 수행하기 위해서는 전체 시퀀스가 필요한 경우가 있다.
-
예를들어 where는 전체 시퀀스를 요구한다. 따라서 무한 시퀀스에 대해서 where를 수행하면 시퀀스 내의 개별 요소가 주어진 조건에 부합하는지를 검사하여 또 다른 무한 시퀀스를 생성하게 된다.
-
Orderby도 정렬을 위해서 전체 시퀀스가 필요하다. Max나 min 또한 where와 유사한 이유로 전체 시퀀스가 필요하다.사실 이러한 몇몇개 작업들은 시퀀스 내의 모든 요소들에 대해 검사하지 않고서는 올바른 결과를 얻을 수 없는 연산들이다.
-
전체 시퀀스가 필요한 메서드를 사용할 때 염두해야 할 점은 아래와 같다 a. 첫째, 시퀀스가 무한정 지속될 가능성이 있다면 이 같은 메서드를 사용할 수 없다. b.시퀀스가 무한이 아니더라도 시퀀스를 필터링하는 쿼리 메서드는 다른 쿼리보다 먼저 수행하는 것이 좋다. 선행 단계에서 컬렉션의 갯수를 줄일 수 있다면 다음부터 실행하는 쿼리의 성능을 개선할 수 있으므로!
결론적으로
거의 대부분의 경우에는 지연 평가를 사용하면 즉시 평가에 비해서 작업의 양도 줄고 유연성도 증가한다. 드문 경우이긴 하지만 즉각적으로 쿼리를 수행하고 그 결과를 가져와야 하는 경우라면 ToList() 나 ToArray()를 사용하면 된다. 하지만 즉시 평가가 반드시 필요한 경우가 아니라면, 대체로 지연 평가를 사용하는 편이 훨씬 낫다.