选项类型基准使用f#



我需要在大量数值模拟中使用Some/None选项。下面的微基准测试给出了Fast = 485Slow = 5890

我不喜欢null,即使我喜欢它们,我也不能使用null,因为The type 'float' does not have 'null' as a proper value

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

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。但是由于option<_>是一个引用类型(null在。net类型系统中必须是一个有效的值),创建Some实例将必然需要堆分配。另一种选择是使用。net System.Nullable<_>类型,它类似于option<_>,除了:

  1. 它是一个值类型,所以不需要堆分配
  2. 它只支持值类型作为元素,所以您可以创建option<string>,但不能创建Nullable<string>。对于您的用例,这似乎是一个不重要的因素。
  3. 它有运行时支持,所以没有值的空框会导致空引用,否则这是不可能的

请记住,您的基准测试只做很少的工作,因此结果可能不是您在实际工作负载中看到的典型结果。如果可能的话,尝试根据您的实际场景使用更有意义的基准测试。

作为旁注,如果您在f#中使用#time指令,而不是使用Stopwatch,则可以获得更有意义的诊断(包括垃圾收集统计信息)。

相关内容

  • 没有找到相关文章

最新更新