仅用于F#Interactive中的变量声明300毫秒?

时间:2012-07-20 20:18:04

标签: f# timer f#-interactive

我正在玩F#Interactive Console并比较一些数字操作的运行时间。在这段代码中,总运行时间似乎只是重复一个变量的声明。

在VS 2010中,我做了:

open System.Diagnostics
let mutable a=1

然后我选择以下内容并使用Alt + Enter

运行它
let stopWatch = Stopwatch.StartNew()
for i=1 to 200100100 do
    a <- a + 1
stopWatch.Stop()
printfn "stopWatch.Elapsed: %f" stopWatch.Elapsed.TotalMilliseconds

需要更多或更少:320毫秒

现在我选择此项并点击Alt + Enter:

let mutable a=1
let stopWatch = Stopwatch.StartNew()
for i=1 to 200100100 do
    a <- a + 1
stopWatch.Stop()
printfn "stopWatch.Elapsed: %f" stopWatch.Elapsed.TotalMilliseconds

几乎翻倍:620毫秒

相同的块,但包括顶部的声明几乎翻倍。因为我在Stopwatch.StartNew()之前声明变量,不应该是一样的吗?这与交互式控制台有关吗? 我使用#time指令得到了相同的结果。

2 个答案:

答案 0 :(得分:4)

我不相信任何答案都是对的。我认为a在两种情况下都表示相同。而且,我的意思是一个单独的类型被动态地包装可变值(当然在堆上!)。它需要这样做,因为在这两种情况下,a都是顶级绑定,可以通过后续交互进行访问。

所有这一切,我的理论是这样的:在第一种情况下,FSI发出的动态类型在交互结束时被加载,以便输出其默认值。但是,在第二种情况下,类型换行aStopWatch启动后在循环中首次访问时才会加载。

答案 1 :(得分:3)

Daniel是对的 - 如果你在一个单独的FSI交互中定义一个变量,那么它的表示方式就不同了。

要获得正确的比较,您需要在两种情况下将变量声明为local。最简单的方法是将代码嵌套在do下(将do下的所有内容转换为本地范围),然后立即评估整个do块。请参阅以下两个示例的结果:

// A version with variable declaration excluded
do
  let mutable a=1 
  let stopWatch = Stopwatch.StartNew() 
  for i=1 to 200100100 do 
    a <- a + 1 
  stopWatch.Stop() 
  printfn "stopWatch.Elapsed: %f" stopWatch.Elapsed.TotalMilliseconds 

// A version with variable declaration included
do
  let stopWatch = Stopwatch.StartNew() 
  let mutable a=1 
  for i=1 to 200100100 do 
    a <- a + 1 
  stopWatch.Stop() 
  printfn "stopWatch.Elapsed: %f" stopWatch.Elapsed.TotalMilliseconds 

我运行它时得到的差异是不可测量的。