为什么这个定时功能总是测量0ms?

buc*_*ley 5 f#

我正在计算一些算法,并在下面提出了时间函数.但是,它总是返回0毫秒.

问题是为什么它显然需要几秒钟时总是0毫秒.我是F#开发人员的开始,所以我可能错过了一些概念.

请注意,问题不是关于更高效的Fibonacci算法,我也知道该函数测量的是实际世界时间而不是CPU时间(可以通过Sys.time()获得)

let time f x =
   let timer = new System.Diagnostics.Stopwatch()
   timer. Start ( )
   try f x finally
   printf "Took %dms" timer.ElapsedMilliseconds;;

let rec fib x = 
   if x < 2 then 1
   else fib(x-1) + fib(x-2)

time Array.iter (fun x -> ignore (fib x) ) [| 1 .. 40 |] 
Run Code Online (Sandbox Code Playgroud)

感谢您为F#开发人员提供的任何帮助和指示

问候,汤姆

cfe*_*ern 6

问题是你的时间函数需要一个单参数函数,但是你用两个参数调用它:

time Array.iter (fun x -> ...) [|1..40|]
                 ^- first arg   ^- second arg
Run Code Online (Sandbox Code Playgroud)

要获得所需的结果,请使用括号

time (Array.iter (fun x -> ignore (fib x) )) [| 1 .. 40 |] 
      ^- a single partially curried function  ^- a single argument
Run Code Online (Sandbox Code Playgroud)

例如在FSI中:

> time ( Array.iter (fun x -> ignore (fib x) ) ) [| 1 .. 40 |];;
Took 6589msval it : unit = ()
Run Code Online (Sandbox Code Playgroud)

更好的是,如果您在F#interactive中进行测试,请使用该#time指令,FSI将为您完成计时.例:

> #time;;

--> Timing now on

> Array.iter (fun x -> ignore (fib x) ) [| 1 .. 40 |];;
Real: 00:00:06.816, CPU: 00:00:06.218, GC gen0: 0, gen1: 0, gen2: 0
val it : unit = ()
Run Code Online (Sandbox Code Playgroud)


kvb*_*kvb 5

你的问题是,由于函数应用程序的工作原理,你这样做:

((time Array.iter) (fun x -> ignore (fib x))) [| 1 .. 40 |]
Run Code Online (Sandbox Code Playgroud)

因此,您需要计算应用于Array.iter函数值所需的时间fun x -> ignore (fib x),这不会花费很长时间,并导致另一个类型的函数int array -> (),然后您将应用于该函数[| 1 .. 40 |].相反,你应该尝试

time (Array.iter (fun x -> ignore (fib x))) [| 1 .. 40 |] 
Run Code Online (Sandbox Code Playgroud)