[.net] 지연 초기화 란 무엇이며 왜 유용합니까?

개체의 지연 초기화 란 무엇입니까? 어떻게하고 장점은 무엇입니까?



답변

지연 초기화는 실제로 필요하기 직전까지 (잠재적으로 비용이 많이 드는) 개체 생성을 연기하는 성능 최적화입니다.

한 가지 좋은 예는 데이터베이스 연결을 미리 생성하지 않고 데이터베이스에서 데이터를 가져 오기 직전에 만드는 것입니다.

이 작업을 수행하는 주요 이유는 필요하지 않은 경우 개체를 완전히 생성하는 것을 피할 수 있다는 것입니다.


답변

다른 사람들이 언급했듯이 지연 초기화는 구성 요소 또는 개체가 사용될 때까지 초기화를 지연시킵니다. 당신은 게으른 초기화를 볼 수 있습니다 런타임 응용 프로그램YAGNI 원칙 – ” You ain't gonna need it

지연 초기화의 애플리케이션 관점에서 얻을 수있는 이점은 사용자가 사용하지 않을 기능에 대해 초기화 시간을 지불 할 필요가 없다는 것입니다. 응용 프로그램의 모든 구성 요소를 먼저 초기화한다고 가정합니다. 이로 인해 시작 시간이 길어질 수 있습니다. 사용자는 애플리케이션을 사용할 준비가되기까지 수십 초 또는 몇 분을 기다려야합니다. 그들은 결코 사용하지 않거나 즉시 사용하지 않을 수있는 기능의 초기화를 기다리며 비용을 지불하고 있습니다.

대신 사용 시간까지 해당 구성 요소 초기화를 연기하면 응용 프로그램이 훨씬 더 빨리 시작됩니다. 사용자는 다른 구성 요소를 사용할 때 여전히 시작 비용을 지불해야하지만 해당 비용은 프로그램 실행 전반에 걸쳐 상각되고 처음으로 압축되지 않으며 사용자는 이러한 개체의 초기화 시간을 현재의 기능과 연결할 수 있습니다. 사용.


답변

지연 초기화는 객체가 실제로 처음 사용될 때까지 객체 생성을 연기하는 개념입니다. 올바르게 사용하면 성능이 크게 향상 될 수 있습니다.

개인적으로 저는 .NET 2.0에서 직접 ORM을 만들 때 Lazy Initialization을 사용했습니다. 데이터베이스에서 내 컬렉션을로드 할 때 컬렉션의 실제 항목이 지연 초기화되었습니다. 즉, 컬렉션이 빠르게 생성되었지만 각 개체는 필요한 경우에만로드되었습니다.

Singleton 패턴에 익숙하다면 지연 초기화가 작동하는 것을 보았을 것입니다.

public class SomeClassSingleton
{
    private static SomeClass _instance = null;

    private SomeClassSingleton()
    {
    }

    public static SomeClass GetInstance()
    {
        if(_instance == null)
            _instance = new SomeClassSingleton();

        return _instance;
    }
}

이 경우 SomeClass의 인스턴스는 SomeClassSingleton 소비자가 처음으로 필요할 때까지 초기화되지 않습니다.


답변

일반적인 컴퓨팅 용어에서 ‘지연 평가’는 실제로 필요할 때까지 처리를 연기하는 것을 의미합니다. 주요 아이디어는 필요하지 않거나 사용하기 전에 값이 변경되는 경우 비용이 많이 드는 작업을 피할 수 있다는 것입니다.

이에 대한 간단한 예는 System.Exception.StackTrace입니다. 이것은 예외에 대한 문자열 속성이지만 실제로 액세스 할 때까지 빌드되지 않습니다. 내부적으로는 다음과 같은 작업을 수행합니다.

String StackTrace{
  get{
    if(_stackTrace==null){
      _stackTrace = buildStackTrace();
    }
    return _stackTrace;
  }
}

이것은 누군가가 그것이 무엇인지보고 싶어 할 때까지 실제로 buildStackTrace를 호출하는 오버 헤드를 줄여줍니다.

속성은 이러한 유형의 동작을 제공하는 한 가지 방법입니다.


답변

여기 에서 샘플 코드로 지연 초기화 에 대해 읽을 수 있습니다 .

  • 만드는 데 비용이 많이 드는 개체가 있고 프로그램에서 사용하지 않을 수 있습니다. 예를 들어, 초기화하려면 데이터베이스 연결이 필요한 Order 개체의 큰 배열을 포함하는 Orders 속성이있는 Customer 개체가 메모리에 있다고 가정합니다. 사용자가 주문을 표시하거나 계산에 데이터를 사용하도록 요청하지 않으면 시스템 메모리 또는 컴퓨팅주기를 사용하여 생성 할 이유가 없습니다. Lazy를 사용하여 지연 초기화를 위해 Orders 개체를 선언하면 개체가 사용되지 않을 때 시스템 리소스가 낭비되는 것을 방지 할 수 있습니다.

  • 생성하는 데 비용이 많이 드는 객체가 있고 다른 비용이 많이 드는 작업이 완료 될 때까지 생성을 연기하려는 경우. 예를 들어 프로그램이 시작될 때 여러 개체 인스턴스를로드하지만 그중 일부만 즉시 필요하다고 가정합니다. 필요한 개체가 만들어 질 때까지 필요하지 않은 개체의 초기화를 연기하여 프로그램의 시작 성능을 향상시킬 수 있습니다.


답변

객체의 지연 초기화는 처음 사용될 때까지 생성이 지연된다는 것을 의미합니다. (이 주제에서 지연 초기화 및 지연 인스턴스화라는 용어는 동의어입니다.) 지연 초기화는 주로 성능을 향상시키고 낭비적인 계산을 방지하며 프로그램 메모리 요구 사항을 줄이는 데 사용됩니다. 다음은 가장 일반적인 시나리오입니다.

만드는 데 비용이 많이 드는 개체가 있고 프로그램에서 사용하지 않을 수 있습니다. 예를 들어, 초기화하려면 데이터베이스 연결이 필요한 Order 개체의 큰 배열을 포함하는 Orders 속성이있는 Customer 개체가 메모리에 있다고 가정합니다. 사용자가 주문을 표시하거나 계산에 데이터를 사용하도록 요청하지 않으면 시스템 메모리 또는 컴퓨팅주기를 사용하여 생성 할 이유가 없습니다. Lazy를 사용하여 지연 초기화를 위해 Orders 개체를 선언하면 개체가 사용되지 않을 때 시스템 리소스가 낭비되는 것을 방지 할 수 있습니다.

생성하는 데 비용이 많이 드는 객체가 있고 다른 비용이 많이 드는 작업이 완료 될 때까지 생성을 연기하려는 경우. 예를 들어 프로그램이 시작될 때 여러 개체 인스턴스를로드하지만 그중 일부만 즉시 필요하다고 가정합니다. 필요한 개체가 만들어 질 때까지 필요하지 않은 개체의 초기화를 연기하여 프로그램의 시작 성능을 향상시킬 수 있습니다.

직접 코드를 작성하여 지연 초기화를 수행 할 수 있지만 대신 지연을 사용하는 것이 좋습니다. Lazy 및 관련 유형도 스레드 안전성을 지원하고 일관된 예외 전파 정책을 제공합니다.


답변

//Lazy instantiation delays certain tasks. 
//It typically improves the startup time of a C# application.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LazyLoad
{
    class Program
    {
        static void Main(string[] args)
        {
            Lazy<MyClass> MyLazyClass = new Lazy<MyClass>(); // create lazy class
            Console.WriteLine("IsValueCreated = {0}",MyLazyClass.IsValueCreated); // print value to check if initialization is over

            MyClass sample = MyLazyClass.Value; // real value Creation Time
            Console.WriteLine("Length = {0}", sample.Length); // print array length

            Console.WriteLine("IsValueCreated = {0}", MyLazyClass.IsValueCreated); // print value to check if initialization is over
            Console.ReadLine();
        }
    }

    class MyClass
    {
        int[] array;
        public MyClass()
        {
            array = new int[10];

        }

        public int Length
        {
            get
            {
                return this.array.Length;
            }
        }
    }
}


// out put

// IsValueCreated = False
// Length = 10
// IsValueCreated = True