2011-01-28 28 views
5

Tôi đang định thời gian một số thuật toán và đã đưa ra hàm thời gian bên dưới. Tuy nhiên, nó luôn trả về 0 ms.Tại sao chức năng định thời này luôn đo 0ms?

Các câu hỏi đặt ra tại sao nó luôn luôn là 0ms khi nó mất một vài giây. Tôi là một nhà phát triển F # đầu nên tôi có thể thiếu một số khái niệm.

Lưu ý rằng vấn đề không phải là về một thuật toán Fibonacci hiệu quả hơn và tôi cũng biết rằng hàm được đo thời gian thế giới thực như trái ngược với thời gian CPU (có thể thu được bằng cách 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 |] 

Nhờ sự giúp đỡ và gợi ý cho một sự khởi đầu F # phát triển

Kính trọng, Tom

Trả lời

6

Vấn đề là chức năng thời gian của bạn hy vọng một hàm một đối số, nhưng bạn đang gọi nó với một hai đối số một:

time Array.iter (fun x -> ...) [|1..40|] 
       ^- first arg ^- second arg 

Để có được kết quả bạn muốn, sử dụng ngoặc

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

Ví dụ trong FSI:

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

Tốt hơn, nếu bạn đang thử nghiệm trong tương tác F #, hãy sử dụng chỉ thị #time và FSI sẽ thực hiện thời gian cho bạn. Ví dụ:

> #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 =() 
5

vấn đề của bạn là do cách thức hoạt động ứng dụng chức năng, bạn đang làm điều này:

((time Array.iter) (fun x -> ignore (fib x))) [| 1 .. 40 |] 

vì vậy bạn thời gian phải mất bao lâu để áp dụng Array.iter để hàm giá trị fun x -> ignore (fib x), mà không mất nhiều thời gian ở tất cả, và kết quả là một chức năng của loại int array ->(), mà bạn đang sau đó áp dụng để [| 1 .. 40 |]. Thay vào đó, bạn nên thử

time (Array.iter (fun x -> ignore (fib x))) [| 1 .. 40 |] 
Các vấn đề liên quan