39

Please post code for displaying time in F#. I noticed that you can measure it from F# interactive with #time directive, but I don't know how to execute program from FSI

Thanks

nanek
  • 391
  • 1
  • 3
  • 3
  • At the time of writing, this wasn't available, but don't use stopwatch and the like, it's extremely flawed. Instead, use Benchmarkdotnet for proper performance measuring, and a profiler. – Abel Aug 25 '20 at 15:31

4 Answers4

58

I would just use the .NET Stopwatch class.

let stopWatch = System.Diagnostics.Stopwatch.StartNew()
...
stopWatch.Stop()
printfn "%f" stopWatch.Elapsed.TotalMilliseconds
Ryan Lundy
  • 204,559
  • 37
  • 180
  • 211
BrokenGlass
  • 158,293
  • 28
  • 286
  • 335
  • But if you're in FSI (F# Interactive REPL), you get more detailed information (CPU time, Real time, GC info). Adding [PrivateEye](http://www.privateeye.io/#) gives even full profiling info from FSI, no extra programming needed. – Abel Sep 18 '16 at 15:23
  • @Abel Do you happen to know if PrivateEye is still available somewhere? The website is unfortunately defunct. I even contacted one of the authors, and he told me I should still be able to find the code somewhere, but then contact broke of... :( – sebhofer Jul 10 '18 at 10:04
  • 1
    @sebhofer, I don't know. I only use Benchmarkdotnet nowadays, gives much info, and takes care of warmup time, averages, outliers, graphs etc etc. It's used for improving the runtime itself, it's pretty darn stable. – Abel Aug 25 '20 at 15:32
  • When I use this with AOT in 8.0-preview5, I get Unhandled Exception: System.NotSupportedException: 'Microsoft.FSharp.Core.PrintfImpl+Specializations`3[System.IO.TextWriter,Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit].CaptureFinal1[System.Int32](Microsoft.FSharp.Core.PrintfImpl+Step[])' is missing native code. MethodInfo.MakeGenericMethod() is not compatible with AOT compilation. Inspect and fix AOT related warnings that were generated when the app was published. For more information see https://aka.ms/nativeaot-compatibility – silvalli Jun 19 '23 at 21:16
32

From msdn:

By itself, #time toggles whether to display performance information. When it is enabled, F# Interactive measures real time, CPU time, and garbage collection information for each section of code that is interpreted and executed.

So to test you function you have to open F# interactive console and execute your function in it (one way to do it is to select your function, right click and chose Execute in Interactive) Then make a call to your function in Interactive like that for example:

// define your function first either in interactive console or in your document:

let square x = x * x

// in interactive
#time
square 10
#time

You will see how much of real time and CPU time were spent on computation and a bit of information from garbage collector

fxdxpz
  • 1,969
  • 17
  • 29
22

Check out the timer function in the F Sharp Programming wikibook. It is defined like this:

let duration f = 
    let timer = new System.Diagnostics.Stopwatch()
    timer.Start()
    let returnValue = f()
    printfn "Elapsed Time: %i" timer.ElapsedMilliseconds
    returnValue    

Whilst being used like this:

let sample() = System.Threading.Thread.Sleep(2)

duration ( fun() -> sample() )
// or
duration sample
Luke Merrett
  • 5,724
  • 8
  • 38
  • 70
David White
  • 3,014
  • 1
  • 32
  • 35
1

You could also create custom computation expression to hide actual measuring logic, e.g.:

timer {
   // your code goes here
}

See more examples here: https://fsharpforfunandprofit.com/posts/computation-expressions-bind/