F# 使用F的选项类型基准#

F# 使用F的选项类型基准#,f#,null,benchmarking,option,F#,Null,Benchmarking,Option,我需要在大型数值模拟中使用一些/没有选项。下面的微基准测试为我提供了Fast=485和Slow=5890 我不喜欢null,即使我喜欢它们,我也不能使用null,因为类型“float”没有“null”作为正确的值 理想情况下,应该有一个编译器选项,将一些/None编译成value/null,这样就不会有运行时惩罚。可能吗?或者我该如何使一些/没有效率 let s = System.Diagnostics.Stopwatch() s.Start() for h in 0 .. 1000 do

我需要在大型数值模拟中使用一些/没有选项。下面的微基准测试为我提供了
Fast=485
Slow=5890

我不喜欢null,即使我喜欢它们,我也不能使用null,因为类型“float”没有“null”作为正确的值

理想情况下,应该有一个编译器选项,将一些/None编译成value/null,这样就不会有运行时惩罚。可能吗?或者我该如何使一些/没有效率

let s = System.Diagnostics.Stopwatch()

s.Start()
for h in 0 .. 1000 do
  Array.init 100000 (fun i -> (float i + 1.)) |> ignore
printfn "Fast = %d" s.ElapsedMilliseconds

s.Restart()
for h in 0 .. 1000 do
  Array.init 100000 (fun i -> Some (float i + 1.)) |> ignore
printfn "Slow = %d" s.ElapsedMilliseconds

None
实际上已经表示为
null
。但是由于
选项
是引用类型(这是
null
在.NET类型系统中成为有效值所必需的),因此创建
某些
实例必然需要堆分配。一种替代方法是使用.NET
System.Nullable
类型,它类似于
选项
,除了:

  • 它是一种值类型,因此不需要堆分配
  • 它只支持值类型作为元素,因此您可以创建一个
    选项
    ,但不能创建一个
    可空的
    。对于您的用例来说,这似乎是一个不重要的因素
  • 它具有运行时支持,因此在没有值的情况下装箱一个null可导致null引用,否则这是不可能的
  • 请记住,您的基准测试所做的工作很少,因此结果可能与您在实际工作负载中看到的结果不同。尽可能根据您的实际场景使用更有意义的基准测试


    另外,如果在F中使用
    #time
    指令而不是使用
    秒表

    的话,您会得到更有意义的诊断(包括垃圾收集统计),真的吗?我不知道时间比秒表好。听起来不错。我应该如何准确地使用Nullable,例如在模式匹配中?@OldrichSvec-嗯,只有两种情况,所以我可能只使用
    如果nbl.HasValue那么。。。nbl.价值。。。否则…
    ,但如果您喜欢使用模式匹配,还可以定义一个
    (|NullableSome | NullableNone |)
    活动模式。