cme*_*ren 8 .net f# lazy-loading
在F#核心库中有高阶函数,它们采用thunk(fun () -> ...),但也可以在概念上采用Lazy<_>,例如Option.defaultWith.Lazy<_>通过lazy关键字,F#具有良好的语法支持,但我不能想到F#核心库中的任何函数Lazy<_>而不是thunk.我猜这是因为使用thunks比使用特定于.NET的Lazy<_>类型更"FP" .
但除了模糊地"减少FP"之外:如果最多需要一次这个值,那么使用Lazy<_>而不是thunk 的实际考虑是什么?例如,是否存在性能差异(CPU和/或分配/内存)?其他问题?用Lazy<_>th而不是thunk 可以更好地解决什么样的情况?
作为一个包装thunk的单独对象,提供同步并保存结果引用,Lazy<_>与简单的thunk相比,有一些额外的开销.
如果你知道你只会评估thunk(最多)一次,我认为如果可以的话你就不会使用函数.你可以在另一个函数中包含对Lazy<_>s 的调用Value,但在这种情况下它没有我所知道的好处.
我记得有一个场景Lazy<_>是有用的,那就是我们在产品中有两个独立的功能标志,如果启用它们,可能需要初始化Orleankka actor系统 - 昂贵的操作,每次应用程序启动时应该只执行一次.
所以我们的选择要么是很多嵌套if的,可变的选项,要么:
let actorSystem = lazy initializeActorSystem ()
if feature1Enabled then
let as = actorSystem.Value
...
if feature2Enabled then
let as = actorSystem.Value
...
Run Code Online (Sandbox Code Playgroud)
与thunk不同,Lazy<_>还允许您检查thunk是否被评估.从同样的问题:
if actorSystem.IsValueCreated then
actorSystem.Value.Dispose()
Run Code Online (Sandbox Code Playgroud)
其他情况通常在你不确定你最多会评估一次thunk时,特别是如果它可以同时发生.我认为我们也有这样的用例,用于读取一些外部配置,而不是本地提供给同时启动的多个组件 - Lazy<_>确保我们只进行一次远程调用(如果需要的话),无论哪个组件首先发现它需要它.
| 归档时间: |
|
| 查看次数: |
136 次 |
| 最近记录: |