Lazy initialization in .NET

Learn how to increase performance of the application using Lazy initialization.

Microsoft .Net framework 4.0 or later version provides a concept called Lazy initialization. Using this concept we can increase the performance while loading time or startup time. To know, where we can implement this concept, just check the below scenario-

Suppose in our application, there are some objects which contain other child objects and to fill those child object we have some logic or computation which takes time. But at the time of application startup, we want only parent class properties; in this case if we will create the object of parent class then it will take time because some part of the time will be consumed to fill the child object.

To avoid this condition, we can implement the concept called Lazy initialization using Lazy<T> of .Net, which will increase the performance.  Here ‘T’ is the type of object that is being lazily initialized.

Code Implementation-

To explore this, I have created two classes- Parent and Child, to maintain parent -child relationship, I have defined 2 properties (LstChild and LstChildLazy) in parent class as child type. Here I am filling dummy data to LstChild without Lazy Class and LstChildLazy with Lazy class.

//Parent Class
    public class ParentClass
    {
         public int intParentID{get;set;}
        public string strParentName{get;set;}

        //Filling child class object without Lazy class
        private List<Child> _lstChild;
        public List<Child> LstChild
        {
            get
            {
                 if (_lstChild == null)
                {
                    _lstChild = new List<Child>();
                     for (int i = 0; i < 1000000; i++)
                     {
                         _lstChild.Add(new Child() { intChildID = i, strChildName = "Name" + i.ToString() });
                     }
                  }
                 return _lstChild;
            }
            set
            {
                _lstChild = value;
             }
        }

        //Filling child class object with Lazy class
        private List<Lazy<Child>> _lstChildLazy;
         public List<Lazy<Child>> LstChildLazy
         {
             get
             {
                 if (_lstChildLazy == null)
                {
                    _lstChildLazy = new List<Lazy<Child>>();
                     for (int i = 0; i < 1000000; i++)
                    {
                       _lstChildLazy.Add(new Lazy<Child>(() => new Child { intChildID = i, strChildName = "Name" + i.ToString() }));
                     }
                 }
                  return _lstChildLazy;
            }
            set
            {
                _lstChildLazy = value;
             }
        }
     }

    //Child Class
    public class Child
    {
         public int intChildID { get; set; }
        public string strChildName { get; set; }
    }

In above code you can see I have same for loop to fill the both properties. Now to track the loading or startup time I have taken 2 buttons and written different code. Check below code-

//Processing items without Lazy Class
        
private void btnProcess_Click(object sender, EventArgs e)
        {
             try
            {
                 //Stopwatch to track the time
                Stopwatch sw = new Stopwatch();
                 sw.Start();
                ParentClass objParentClass = new ParentClass();
                objParentClass.intParentID = 1;
                objParentClass.strParentName = "Parent1";
                 //Getting child class object
               List<Child> objParentClass_Child= objParentClass.LstChild  ;
                sw.Stop();
                lblWithoutLazy.Text = "ElapsedMilliseconds : " + sw.ElapsedMilliseconds.ToString ();
            }
            catch (Exception ex)
             {
                 MessageBox.Show(ex.Message);
             }
         }

         //Processing items with Lazy Class
       private void btnProcessWithLazy_Click(object sender, EventArgs e)
        {
             try
            {
                 //Stopwatch to track the time
                Stopwatch sw = new Stopwatch();
                 sw.Start();
                ParentClass objParentClass = new ParentClass();
                objParentClass.intParentID = 1;
                objParentClass.strParentName = "Parent1";
                 //Getting child class object with Lazy class
               List<Lazy<Child>> objParentClass_Child = objParentClass.LstChildLazy;
                sw.Stop();
                lblWithLazy.Text = "ElapsedMilliseconds: " + sw.ElapsedMilliseconds.ToString();
            }
            catch (Exception ex)
             {
                 MessageBox.Show(ex.Message);
             }
         }


Description-

btnProcess_Click()- This is implemented without Lazy class object
btnProcessWithLazy _Click()- This is implemented with Lazy class object

Now check the below output-



You can see that Lazy initialization is taking less time compare to normal initialization. This implementation increase the application startup or loading time because Lazy initialization occurs the first time the Lazy<T>.Value property is accessed means Lazy loading is initializing the member the first time it is requested. The additional advantage of Lazy<T> class is that be default all the members of this class are thread safe so that members can be shared concurrently with multiple thread.

Point of Interest-

It can be easily identified that the value has been created for object or not by using IsValueCreated property.

Example-


public class clsEmp
    {
        string strFname;
        string strLname;

        public clsEmp()
        {
            strFname = "Jitendra";
            strLname = "Faye";
        }

         public string GetFullName()
        {
            return strFname + " " + strLname;
        }
     }

private void button1_Click(object sender, EventArgs e)
        {
            Lazy<clsEmp> lazyEmp = new Lazy<clsEmp>();
             MessageBox.Show("Value created :" + lazyEmp.IsValueCreated);  // False
            clsEmp objEmp = lazyEmp.Value;
            MessageBox.Show("Value created :" + lazyEmp.IsValueCreated);  // True
            MessageBox.Show("Full Name:" + objEmp.GetFullName());  
   }

For first call of lazyEmp.IsValueCreated return value will be False because in this time no value will be created for Lazy<T> instance.
But once we call lazyEmp.Value then clsEmp class constructor will be executed and allocation will take place. In second call of lazyEmp.IsValueCreated return value will be True.

Lazy loading also reduce the consumption of memory because of on-demand memory allocation.

You can download the complete code from here-

Lazy initialization

By Jitendra Faye   Popularity  (2143 Views)