C#/LINQ

[C#]LINQ 즉시 실행과 지연 실행(Immediate Execution vs Deferred Execution)

DevStory 2022. 8. 15.

즉시 실행과 지연 실행

C#의 LINQ는 두 가지 방식으로 실행됩니다.

 

즉시 실행(Immediate Execution)

- count, average, min, max, ToArray, ToList 등.. 즉시 실행에 포함됩니다.

 

지연 실행(Deferred Execution)

- select, SelectMany, where, Take, Skip 등.. 지연 실행에 포함됩니다.

 

이번 포스팅은 LINQ의 즉시 실행과 지연 실행에 대해 소개합니다.


즉시 실행

즉시 실행은 쿼리를 강제로 실행하고 결과를 바로 가져옵니다.

 

다음 예제는 즉시 실행을 설명하는 소스 코드입니다.

public class Person
{
  public int ID { get; set; }
  public string Name { get; set; }
  public int Age { get; set; }
}

class Program
{
  static void Main(string[] args)
  {
    List<Person> personList = new List<Person>()
    {
      new Person() {ID = 1000, Name = "둘리",   Age = 20},
      new Person() {ID = 2000, Name = "마이콜", Age = 30},
      new Person() {ID = 3000, Name = "고길동", Age = 40}
    };

    // 1. personList에 ToList() 메서드를 사용하여 결과를 바로 가져옵니다.
    IEnumerable<Person> immediateResult = personList.ToList();

    // 2. personList에 새로운 데이터를 추가합니다.
    personList.Add(new Person { ID = 4000, Name = "또치", Age = 50 });

    // 3. 1번 과정에서 반환받은 결과를 출력합니다. 
    foreach (Person person in immediateResult)
    {
      Console.WriteLine("{ ID: " + person.ID + 
          ", Name: " + person.Name + 
          ", Age: " + person.Age + " }");
    }
  }
}

[실행 결과]

{ ID: 1000, Name: 둘리, Age: 20 }
{ ID: 2000, Name: 마이콜, Age: 30 }
{ ID: 3000, Name: 고길동, Age: 40 }

순서 1. 즉시 실행 메서드인 ToList() 메서드를 사용하여 personList가 List로 변환된 결과를 immediateResult에 할당하였습니다.

순서 2. personList에 새로운 데이터를 추가합니다.

순서 3. 1번 과정에서 ToList() 메서드에 의해 반환된 immediateResult에는 personList에 추가된 데이터가 반영되지 않습니다.


지연 실행

지연 실행은 즉시 실행과 다르게 동작합니다.

 

지연 실행 연산자 또는 메서드를 사용하면 쿼리가 바로 실행되지 않고 쿼리 결과를 접근할 때 실행됩니다.

 

다음 예제는 지연 실행을 설명하는 소스 코드입니다.

public class Person
{
  public int ID { get; set; }
  public string Name { get; set; }
  public int Age { get; set; }
}

class Program
{
  static void Main(string[] args)
  {
    List<Person> personList = new List<Person>()
    {
      new Person() {ID = 1000, Name = "둘리",   Age = 20},
      new Person() {ID = 2000, Name = "마이콜", Age = 30},
      new Person() {ID = 3000, Name = "고길동", Age = 40}
    };

    // 1. personList에 select절을 사용하여 결과를 나중에 가져옵니다.
    IEnumerable<Person> deferredResult = (from   person in personList
                                          select person);

    // 2. personList에 새로운 데이터를 추가합니다.
    personList.Add(new Person { ID = 4000, Name = "또치", Age = 50 });

    // 3. 1번 과정에서 반환받은 결과를 출력합니다. 
    foreach (Person person in deferredResult)
    {
      Console.WriteLine("{ ID: " + person.ID + 
          ", Name: " + person.Name + 
          ", Age: " + person.Age + " }");
    }
  }
}

[실행 결과]

{ ID: 1000, Name: 둘리, Age: 20 }
{ ID: 2000, Name: 마이콜, Age: 30 }
{ ID: 3000, Name: 고길동, Age: 40 }
{ ID: 4000, Name: 또치, Age: 50 }

순서 1. 지연 실행 연산자인 select 연산자를 사용하여 질의 결과를 deferredResult에 할당하였습니다.

순서 2. personList에 새로운 데이터를 추가합니다.

순서 3. 2번 과정에서 추가된 데이터가 deferredResult에 반영되었습니다.


지연 실행의 장점

  • 한 번에 복잡한 많은 쿼리가 실행되면 애플리케이션의 성능이 저하됩니다. 지연 실행을 사용하여 불필요한 쿼리 실행을 방지할 수 있습니다.
  • 쿼리가 실행되기 전에 데이터를 추가할 수 있습니다.
  • 쿼리 결과를 접근할 때, 쿼리가 실행되므로 복잡한 쿼리를 단계별로 수행할 수 있습니다.
반응형

댓글