Bev*_*van 89
延迟初始化是一种性能优化,您可以在实际需要之前推迟(可能是昂贵的)对象创建.
一个很好的例子是不预先创建数据库连接,但仅在您需要从数据库获取数据之前.
这样做的关键原因是(通常)如果您从不需要它,您可以避免完全创建对象.
Mic*_*ael 43
正如其他人所提到的,延迟初始化会延迟初始化,直到使用组件或对象.您可以查看延迟初始化为运行应用程序的YAGNI原则 - " You ain't gonna need it
"
从延迟初始化的应用程序角度来看,用户不必为不使用的功能支付初始化时间.假设您要预先初始化应用程序的每个组件.这可能会创建一个可能很长的启动时间 - 用户必须等待几十秒或几分钟才能准备好应用程序.他们正在等待并支付他们可能永远不会使用或不立即使用的功能的初始化.
相反,如果您推迟初始化这些组件直到使用时间,您的应用程序将更快启动.在使用其他组件时,用户仍然需要支付启动成本,但是该成本将在程序运行期间摊销,而不是压缩到开头,用户可以将这些对象的初始化时间与它们的功能相关联.使用.
Jus*_*ner 14
延迟初始化是在实际首次使用对象之前推迟对象创建的概念.如果使用得当,可以显着提高性能.
就个人而言,我在.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;
}
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,SomeClass的实例在SomeClassSingleton使用者首次需要之前不会初始化.
在一般的计算术语中,"延迟评估"意味着将处理推迟到实际需要之前.主要的想法是,如果您不需要昂贵的操作,或者在使用之前价值会发生变化,您有时可以避免代价高昂的操作.
一个简单的例子是System.Exception.StackTrace.这是异常的字符串属性,但在访问它之前它实际上并未构建.在内部它做了类似的事情:
String StackTrace{
get{
if(_stackTrace==null){
_stackTrace = buildStackTrace();
}
return _stackTrace;
}
}
Run Code Online (Sandbox Code Playgroud)
这可以节省实际调用buildStackTrace的开销,直到有人想要查看它是什么.
属性是简单地提供此类行为的一种方法.