ITEM 37 :: EFFECTIVE C#


안녕하세요, 37번째 시간입니다. 날이 가면 갈수록 어려워지는 게 끝이 다가오고 있음을 알려주는 듯 합니다.


이번 챕터는 쿼리를 사용할 때는 즉시 평가보다 지연 평가가 낫다, 입니다. 딱 들어서는 감이 잘 안오는 생소한 단어임이 분명합니다. 일단, 시작해보죠.

설명

  1. 쿼리를 정의한다고 무조건 데이터나 시퀀스를 즉각적으로 가져오는 것은 아니다. 실제로는 어떤 작업을 수행할지에 대한 절차만 정의하는 것인데, 일반적으로 이러한 방식이 더 효과적이며 실제로 쿼리의 결과를 이용하여 순회를 수행해야만 결과 데이터가 생성된다. 이를 지연 평가라고 한다.

  2. 가끔은 이러한 동작 방식보다는 즉각적인 데이터 생성이 필요한 경우도 있다. 마치 일반 변수처럼 즉각적으로 그 값을 얻어오는 것을 즉시 평가라고 한다.

  3. 따라서 쿼리를 작성할 때는 쿼리의 결과를 여러 번 순회하는 경우 어떻게 동작하기를 바라는지를 미리 고려해야 하며, 즉시 데이터의 스냅샷을 얻기 원하는지 (즉시 평가) 혹은, 그 절차만을 기술할지 (지연 평가) 고민할 필요성이 있다.

  4. 예제를 보면 시퀀스는 그 값을 가지고 있는 것이 아니라 시퀀스 내의 개별요소에 해당하는 그 값을 생성하는 방법을 나타내는 코드를 가지고 있는 것이다.

  5. 몇몇의 코드들은 무한 시퀀스가 생성되며 무한 시퀀스 내에서 쿼리구문을 수행하기 위해서는 전체 시퀀스가 필요한 경우가 있다.

  6. 예를들어 where는 전체 시퀀스를 요구한다. 따라서 무한 시퀀스에 대해서 where를 수행하면 시퀀스 내의 개별 요소가 주어진 조건에 부합하는지를 검사하여 또 다른 무한 시퀀스를 생성하게 된다.

  7. Orderby도 정렬을 위해서 전체 시퀀스가 필요하다. Max나 min 또한 where와 유사한 이유로 전체 시퀀스가 필요하다.사실 이러한 몇몇개 작업들은 시퀀스 내의 모든 요소들에 대해 검사하지 않고서는 올바른 결과를 얻을 수 없는 연산들이다.

  8. 전체 시퀀스가 필요한 메서드를 사용할 때 염두해야 할 점은 아래와 같다 a. 첫째, 시퀀스가 무한정 지속될 가능성이 있다면 이 같은 메서드를 사용할 수 없다. b.시퀀스가 무한이 아니더라도 시퀀스를 필터링하는 쿼리 메서드는 다른 쿼리보다 먼저 수행하는 것이 좋다. 선행 단계에서 컬렉션의 갯수를 줄일 수 있다면 다음부터 실행하는 쿼리의 성능을 개선할 수 있으므로!

결론적으로

거의 대부분의 경우에는 지연 평가를 사용하면 즉시 평가에 비해서 작업의 양도 줄고 유연성도 증가한다. 드문 경우이긴 하지만 즉각적으로 쿼리를 수행하고 그 결과를 가져와야 하는 경우라면 ToList() 나 ToArray()를 사용하면 된다. 하지만 즉시 평가가 반드시 필요한 경우가 아니라면, 대체로 지연 평가를 사용하는 편이 훨씬 낫다.