gpt4 book ai didi

c# - LazyInitializer 与 Lazy 类。何时使用每一个

转载 作者:IT王子 更新时间:2023-10-29 04:04:45 26 4
gpt4 key购买 nike

LazyInitializer 之间有什么区别?和 Lazy<T>类?我知道他们都只会按需初始化对象。我什么时候需要使用它们中的每一个?

最佳答案

我不确定你是否还在研究这个,但我不得不深入研究这两个 Lazy<T> 的细节和 LazyInitializer.EnsureInitialized<T>()最近,所以我想我应该分享我的发现。

首先,一些数字。我使用这两种方法对一千万个值的批处理使用这两种方法运行基准测试,使用 GC.GetTotalMemory(true) 测试内存使用情况。并得到 Stopwatch实例化、首次值访问和后续值访问的时间安排:

Lazy<T> Memory Use:                  320,000,000 bytes (32B/instance)
EnsureInitialized<T>() Memory Use: N/A

Lazy<T> Instantiation Time: 622.01 ms
EnsureInitialized<T>() Inst. Time: N/A

Lazy<T> First Access: 1,373.50 ms
EnsureInitialized<T>() First Access: 72.94 ms

Lazy<T> Subsequent Accesses: 18.51 ms
EnsureInitialized<T>() Subsequent: 13.75 ms

(我将 LazyThreadSafetyMode.PublicationOnlyLazy<T>'s 一起使用,这看起来与 LazyInitializer 默认采用的线程安全方法相同。)

如您所见,在这种情况下,除非我以某种方式搞砸了我的测试(绝不可能!)LazyInitializer几乎在所有可量化的方面都表现出色。它没有内存或实例化开销,而且创建和检索值的速度都更快。

那么,为什么要使用 Lazy<T> ?好吧,首先,这些是我的 x64 系统上的测试结果,在其他情况下您可能会得到不同的结果。

Lazy<T>也可以产生更清晰和更简洁的代码。 return myLazy.Value;return LazyInitializer.EnsureInitialized(ref myValue, () => GetValue(foo));友好多了

此外,Lazy<T>如果你正在处理一个值类型,或者处理一个可以合法地是 null 的引用类型,这会让事情变得简单得多.与 LazyInitializer ,您必须使用第二个 bool 字段来跟踪该值是否已初始化,从而加剧了代码清晰度问题。 Lazy<T>如果您想要更严格的线程安全,使用起来也更简单。

在宏伟的计划中,对于很多应用程序来说,大部分开销可能可以忽略不计(尽管并非总是如此——我开始研究这个的原因是因为我正在开发一个涉及数百万非常小的懒惰的应用程序-加载的值,以及 Lazy<T> 的每个实例 32 字节的开销实际上开始变得不方便)。

最后,除非您的应用程序非常占用内存,否则我认为这通常取决于个人喜好。对于非空引用类型,我个人认为LazyInitializer.EnsureInitialized<T>()是一种更优雅的方法,但我也可以挖掘代码清晰度的论点。

关于c# - LazyInitializer 与 Lazy<T> 类。何时使用每一个,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12007267/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com