什么是对象的懒初始化?如何实现它,有哪些优点?
延迟初始化(Lazy Initialization)是一种性能优化方法,它推迟(可能代价高昂的)对象创建,直到你实际需要使用它。
一个好的例子就是不提前创建数据库连接,在你需要从数据库获取数据之前才进行创建。
这样做的主要原因是,如果你从未需要使用该对象,通常可以避免完全创建它。
懒加载是一种将对象的创建推迟到首次使用对象时才进行的概念。如果使用得当,可以显著提高性能。
就我个人而言,在 .NET 2.0 中创建自己的 ORM 时使用了懒加载。从数据库加载集合时,集合中的实际项是惰性初始化的。这意味着集合可以快速创建,但每个对象只在需要时加载。
如果您熟悉 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;
}
}
在这里,您可以阅读有关延迟初始化的内容以及示例代码。
当您拥有一个昂贵的对象,并且程序可能不会使用它时。例如,假设您在内存中有一个客户对象,它具有包含大量订单对象的订单属性,为了初始化需要数据库连接。如果用户从未要求显示订单或在计算中使用数据,则没有理由使用系统内存或计算周期来创建它。通过使用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
就我目前对于延迟初始化的理解,程序不会一次性加载/请求所有数据。它会在需要使用时从例如SQL服务器中请求。
如果你有一个包含大量子表的大型表格数据库,并且除非进入“编辑”或“查看详细信息”,否则不需要来自其他表格的详细信息,则延迟初始化将帮助应用程序更快地运行,并在需要时首先“懒加载”详细数据。
在SQL或LINQ中,您可以针对每个数据元素设置此“设置”。
希望这对您的问题有所帮助?
Web客户端(例如浏览器)也是如此。图像在HTML之后进行“懒加载”,而如果正确使用,AJAX也是“一种延迟初始化”。
其他人谈到了它的好处,但是要小心它的问题; 就像 Uncle Bob 所说,当使用惰性初始化/评估时,您会
Lazy
的用例/原因:https://dev59.com/I2kv5IYBdhLWcg3wfA4P#15894928。这个建议恰好解决了我们需要解决的问题 - 使用Lazy
作为关键原则。 - lev haikin