【问题标题】:Is F# Interactive supposed to be much slower than compiled?F# Interactive 应该比编译慢得多吗?
【发布时间】:2016-02-10 11:05:08
【问题描述】:

我已经使用 F# 将近六个月了,并且非常确定 F# Interactive 应该具有与编译后相同的性能,以至于当我费心对其进行基准测试时,我确信这是某种编译器错误。虽然现在我想到在打开问题之前我应该​​先检查这里。

对我来说,它大约慢了 3 倍,而且优化开关似乎根本没有做任何事情。

这应该是标准行为吗?如果是这样,我真的被#time 指令控制了。我知道在这个Reddit thread 上求和 1 亿个元素需要多长时间。

更新:

感谢 FuleSnabel,我发现了一些东西。

我尝试从 fsianycpu.exe(这是默认的 F# Interactive)和 fsi.exe 运行示例脚本,两次运行的时间不同。第一次为 134 毫秒,后一次为 78 毫秒。这两个时序也分别对应于未优化和优化二进制文件的时序。

更令人困惑的是,我用来编译的第一个项目是我正在制作的游戏库(以脚本形式)的一部分,它拒绝编译优化的二进制文件,而是切换到未优化的一个没有通知我。我必须开始一个新项目才能正确编译。其他测试正确编译是一个奇迹。

所以基本上,这里发生了一些奇怪的事情,我应该考虑将 fsianycpu.exe 切换为 fsi.exe 作为默认解释器。

【问题讨论】:

  • 我认为没有人能告诉你比 Reddit 上已有的更多信息了 - 你为什么不等你的 github 票?

标签: f#


【解决方案1】:

我在 pastebin 中尝试了示例代码,但没有看到您描述的行为。这是我的性能运行的结果:

.\bin\Release\ConsoleApplication3.exe
Total iterations: 300000000, Outer: 10000, Inner: 30000
reduce sequence of list, result 450015000, time 2836 ms
reduce array, result 450015000, time 594 ms
for loop array, result 450015000, time 180 ms
reduce list, result 450015000, time 593 ms
fsi -O --exec .\Interactive.fsx
Total iterations: 300000000, Outer: 10000, Inner: 30000
reduce sequence of list, result 450015000, time 2617 ms
reduce array, result 450015000, time 589 ms
for loop array, result 450015000, time 168 ms
reduce list, result 450015000, time 603 ms

预计 Seq.reduce 将是最慢的,for 循环最快,并且列表/数组上的 reduce 大致相似(这假定列表元素的局部性无法保证)。

我重写了您的代码,以允许在内存不足的情况下进行更长时间的运行,并改善数据的缓存局部性。在短期运行时,测量的不确定性使得比较数据变得困难。

程序.fs:

module fs

let stopWatch = 
  let sw = new System.Diagnostics.Stopwatch()
  sw.Start ()
  sw

let total = 300000000
let outer = 10000
let inner = total / outer

let timeIt (name : string) (a : unit -> 'T) : unit =
  let t = stopWatch.ElapsedMilliseconds
  let v = a ()
  for i = 2 to outer do
    a () |> ignore
  let d = stopWatch.ElapsedMilliseconds - t
  printfn "%s, result %A, time %d ms" name v d

[<EntryPoint>]
let sumTest(args) = 
  let numsList = [1..inner]
  let numsArray = [|1..inner|]

  printfn "Total iterations: %d, Outer: %d, Inner: %d" total outer inner

  let sumsSeqReduce () = Seq.reduce (+) numsList
  timeIt "reduce sequence of list" sumsSeqReduce

  let sumsArray () = Array.reduce (+) numsArray
  timeIt "reduce array" sumsArray

  let sumsLoop () =
    let mutable total = 0
    for i in 0 .. inner - 1 do
      total <- total + numsArray.[i]
    total

  timeIt "for loop array" sumsLoop

  let sumsListReduce () = List.reduce (+) numsList

  timeIt "reduce list" sumsListReduce

  0

Interactive.fsx:

#load "Program.fs"
fs.sumTest [||]

PS。我正在使用 Visual Studio 2015 在 Windows 上运行。32 位或 64 位似乎只有微小的差异

【讨论】:

  • 我这边发生了一些奇怪的事情。查看我的评论更新。
  • 删除-O 开关是否会给您带来性能差异?对我来说不是。
猜你喜欢
  • 1970-01-01
  • 2012-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-20
  • 1970-01-01
  • 2016-03-14
相关资源
最近更新 更多