When to lazy load?

后端 未结 8 1831
庸人自扰
庸人自扰 2020-12-31 17:14

I lazy load all my members. I have been doing this for a while and simply taken lazy load to be a good thing at face value.

Let\'s say we have

publi         


        
相关标签:
8条回答
  • 2020-12-31 17:27

    First of all, initializing a member inside the constructor isn't lazy loading.

    Lazy Loading is initializing the member the first time it is requested. A simple example in .NET (with some double-check locking so we don't have threading issues):

    public class SomeClass
    {
        private object _lockObj = new object();
        private SomeReferenceType _someProperty;
    
        public SomeReferenceType SomeProperty
        {
            get
            {
                if(_someProperty== null)
                {
                    lock(_lockObj)
                    {
                        if(_someProperty== null)
                        {
                            _someProperty= new SomeReferenceType();
                        }
                    }
                }
                return _someProperty;
            }
            set { _someProperty = value; }
        }
    }
    

    Luckily, if you're using .NET 4, you can now user the Lazy<T> Class which handles the issues for you and makes things a lot easier.

    Second of all, lazy loading is a good idea when you have many members that could be costly to load and you're sure that you're going to be using all of those values. That cost would cause the type to be un-necessarily slow to instantiate.

    Lazy Loading just for the sake of lazy loading is adding unnecessary complexity to your code and could cause issues down the road if done improperly (when dealing with threading, for example).

    0 讨论(0)
  • 2020-12-31 17:29

    From the code I am seeing, you are not doing lazy load. You are initializing members in the constructor, which always happens and happens very soon in the lifetime of the instance.

    Hence, I am wondering, what is not-lazy loading for you?

    Lazy loading is usually when you only initialize something when you are accessing it.

    Here an example, using .NET 4.0 Lazy class, which helps you in doing just that, lazy loading:

    public class Foo
    {
        private Lazy<int> _value = new Lazy<int>(() => 3);
    
        public int Value { get { return _value.Value; } }
    }
    

    Regarding thread-safety - you can pass a second argument LazyThreadSafetyMode which knows two ways to specify thread-safety: One in which execution of the initialization method may happen several times, but where all threads get the value that was created first, or one where the execution is also protected against being run several times.

    0 讨论(0)
  • 2020-12-31 17:30

    this is not lazy loading.

    lazy loading would mean that you just load the value at the moment of a real access (which doesnt happen in the initializer)

    lazy loading is something like that:

    private SomeClass _someRef = null;
    public SomeClass SomeRef
    {
      get
      {
        if(_someRef == null)
        {
           //initialisation just in case of access
           _someRef = new  SomeClass();
        }
        return _someRef;
      }
    }
    
    0 讨论(0)
  • 2020-12-31 17:31

    A real lazy-loaded property for an int might look something like this:

    private int? _heavyLoadedInt;
    
    public int HeavyLoading
    {
        get
        {
            if (_heavyLoadedInt == null)
                _heavyLoadedInt = DoHeavyLoading();
            return _heavyLoadedInt.Value;
        }
    }
    

    Now if you look at this, you’ll see that there is some overhead here: You have to store the value in a nullable (extra memory); check it for null at every access, and retrieve the value from the nullable at every access.

    If your integer really requires some seriously heavy computation, then this construct makes sense. But new int() is not a heavy computation, it just returns 0. The overhead is tiny, but if you add this overhead to an even tinier operation (which is to read an integer), it makes no sense.

    0 讨论(0)
  • 2020-12-31 17:36

    Lazy loading is essential when the cost of object creation is very high and the use of the object is vey rare. So, this is the scenario where it's worth implementing lazy loading. The fundamental idea of lazy loading is to load object/data when needed

    0 讨论(0)
  • 2020-12-31 17:40

    That's not really a lazy load. That's initializing on construction. Typically what we mean in lazy loading is to construct the item the first time it's referenced.

        private string _someField;
    
        public string SomeField
        {
            get 
            {
                // we'd also want to do synchronization if multi-threading.
                if (_someField == null)
                {
                    _someField = new String('-', 1000000);
                }
    
                return _someField;
            }
        }
    

    It used to be one of the typical ways to Lazy load was a check,lock,check so that you don't lock if it's already created, but since it's possible for two items to pass the check and wait for the lock, you check again in the lock:

    public class SomeClass
    {
        private string _someField;
    
        private readonly object _lazyLock = new object();
    
    
        public string SomeField
        {
            get 
            {
                // we'd also want to do synchronization if multi-threading.
                if (_someField == null)
                {
                    lock (_lazyLock)
                    {
                        if (_someField == null)
                        {
                            _someField = new String('-', 1000000);
                        }
                    }
                }
    
                return _someField;
            }
        }
    }
    

    There are various ways to do this, in fact in .NET 4.0, there is a Lazy<T> type that can help you do thread-safe lazy-loading easily.

    public class SomeClass
    {
        private readonly Lazy<string> _someField = new Lazy<string>(() => new string('-', 10000000), true);
    
        private readonly object _lazyLock = new object();
    
    
        public string SomeField
        {
            get
            {
                return _someField.Value;
            }
        }
    }
    

    As to the why, typically lazy-loading is a good scheme if the object you are creating tends to be expensive (memory or time) and there's no guarantee you'll need it. If you are reasonably sure it will always be used, then you should just construct it outright.

    0 讨论(0)
提交回复
热议问题