我正在玩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指令得到了相同的结果。
答案 0 :(得分:4)
我不相信任何答案都是对的。我认为a
在两种情况下都表示相同。而且,我的意思是一个单独的类型被动态地包装可变值(当然在堆上!)。它需要这样做,因为在这两种情况下,a
都是顶级绑定,可以通过后续交互进行访问。
所有这一切,我的理论是这样的:在第一种情况下,FSI发出的动态类型在交互结束时被加载,以便输出其默认值。但是,在第二种情况下,类型换行a
在StopWatch
启动后在循环中首次访问时才会加载。
答案 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
我运行它时得到的差异是不可测量的。